Implementing jwt and adding tests

This commit is contained in:
Nick Sharp 2017-06-28 21:43:37 +01:00
parent ec0f3b32e4
commit 9532d940f1
10 changed files with 219 additions and 72 deletions

View File

@ -19,6 +19,19 @@ namespace Ocelot.Authentication.Handler.Creator
{ {
var builder = app.New(); var builder = app.New();
if (authOptions.Provider.ToLower() == "jwt")
{
var authenticationConfig = authOptions.Config as JwtConfig;
builder.UseJwtBearerAuthentication(
new JwtBearerOptions()
{
Authority = authenticationConfig.Authority,
Audience = authenticationConfig.Audience
});
}
else
{
var authenticationConfig = authOptions.Config as IdentityServerConfig; var authenticationConfig = authOptions.Config as IdentityServerConfig;
builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
@ -30,6 +43,7 @@ namespace Ocelot.Authentication.Handler.Creator
SupportedTokens = SupportedTokens.Both, SupportedTokens = SupportedTokens.Both,
ApiSecret = authenticationConfig.ApiSecret ApiSecret = authenticationConfig.ApiSecret
}); });
}
var authenticationNext = builder.Build(); var authenticationNext = builder.Build();

View File

@ -2,6 +2,7 @@
{ {
public enum SupportedAuthenticationProviders public enum SupportedAuthenticationProviders
{ {
IdentityServer IdentityServer,
Jwt
} }
} }

View File

@ -36,5 +36,18 @@ namespace Ocelot.Configuration
public bool RequireHttps { get; private set; } public bool RequireHttps { get; private set; }
} }
public class JwtConfig : IAuthenticationConfig
{
public JwtConfig(string authority, string audience)
{
Audience = audience;
Authority = authority;
}
public string Audience { get; }
public string Authority { get; }
}
public interface IAuthenticationConfig {} public interface IAuthenticationConfig {}
} }

View File

@ -9,7 +9,7 @@ namespace Ocelot.Configuration.Builder
private List<string> _allowedScopes; private List<string> _allowedScopes;
private IdentityServerConfig _identityServerConfig; private IAuthenticationConfig _identityServerConfig;
public AuthenticationOptionsBuilder WithProvider(string provider) public AuthenticationOptionsBuilder WithProvider(string provider)
{ {
@ -23,7 +23,7 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public AuthenticationOptionsBuilder WithIdntityServerConfigConfiguration(IdentityServerConfig config) public AuthenticationOptionsBuilder WithConfig(IAuthenticationConfig config)
{ {
_identityServerConfig = config; _identityServerConfig = config;
return this; return this;
@ -66,11 +66,33 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public IdentityServerConfig Build() public IdentityServerConfig Build()
{ {
return new IdentityServerConfig(_providerRootUrl, _apiName, _requireHttps, _apiSecret); return new IdentityServerConfig(_providerRootUrl, _apiName, _requireHttps, _apiSecret);
} }
} }
public class JwtConfigBuilder
{
public string _authority;
public string _audience;
public JwtConfigBuilder WithAuthority(string authority)
{
_authority = authority;
return this;
}
public JwtConfigBuilder WithAudience(string audience)
{
_audience = audience;
return this;
}
public JwtConfig Build()
{
return new JwtConfig(_authority, _audience);
}
}
} }

View File

@ -7,25 +7,13 @@ namespace Ocelot.Configuration.Creator
{ {
public AuthenticationOptions Create(FileReRoute fileReRoute) public AuthenticationOptions Create(FileReRoute fileReRoute)
{ {
var authenticationConfig = new IdentityServerConfigCreator().Create(fileReRoute.AuthenticationOptions); var authenticationConfig = new ConfigCreator().Create(fileReRoute.AuthenticationOptions);
return new AuthenticationOptionsBuilder() return new AuthenticationOptionsBuilder()
.WithProvider(fileReRoute.AuthenticationOptions?.Provider) .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes) .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
.WithIdntityServerConfigConfiguration(authenticationConfig) .WithConfig(authenticationConfig)
.Build(); .Build();
} }
} }
public class IdentityServerConfigCreator
{
public IdentityServerConfig Create(FileAuthenticationOptions authenticationOptions)
{
return new IdentityServerConfigBuilder()
.WithApiName(authenticationOptions.IdentityServerConfig?.ApiName)
.WithApiSecret(authenticationOptions.IdentityServerConfig?.ApiSecret)
.WithProviderRootUrl(authenticationOptions.IdentityServerConfig?.ProviderRootUrl)
.WithRequireHttps(authenticationOptions.IdentityServerConfig.RequireHttps).Build();
}
}
} }

View File

@ -0,0 +1,35 @@
namespace Ocelot.Configuration.Creator
{
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
public class ConfigCreator
{
public IAuthenticationConfig Create(FileAuthenticationOptions authenticationOptions)
{
if (authenticationOptions.Provider == "Jwt")
{
return CreateJwt(authenticationOptions);
}
return CreateIdentityServer(authenticationOptions);
}
private JwtConfig CreateJwt(FileAuthenticationOptions authenticationOptions)
{
return new JwtConfigBuilder()
.WithAudience(authenticationOptions.JwtConfig?.Audience)
.WithAuthority(authenticationOptions.JwtConfig?.Authority)
.Build();
}
private IdentityServerConfig CreateIdentityServer(FileAuthenticationOptions authenticationOptions)
{
return new IdentityServerConfigBuilder()
.WithApiName(authenticationOptions.IdentityServerConfig?.ApiName)
.WithApiSecret(authenticationOptions.IdentityServerConfig?.ApiSecret)
.WithProviderRootUrl(authenticationOptions.IdentityServerConfig?.ProviderRootUrl)
.WithRequireHttps(authenticationOptions.IdentityServerConfig.RequireHttps).Build();
}
}
}

View File

@ -8,11 +8,13 @@ namespace Ocelot.Configuration.File
{ {
AllowedScopes = new List<string>(); AllowedScopes = new List<string>();
IdentityServerConfig = new FileIdentityServerConfig(); IdentityServerConfig = new FileIdentityServerConfig();
JwtConfig = new FileJwtConfig();
} }
public string Provider { get; set; } public string Provider { get; set; }
public List<string> AllowedScopes { get; set; } public List<string> AllowedScopes { get; set; }
public FileIdentityServerConfig IdentityServerConfig { get; set; } public FileIdentityServerConfig IdentityServerConfig { get; set; }
public FileJwtConfig JwtConfig { get; set; }
} }
public class FileIdentityServerConfig public class FileIdentityServerConfig
@ -22,4 +24,11 @@ namespace Ocelot.Configuration.File
public bool RequireHttps { get; set; } public bool RequireHttps { get; set; }
public string ApiSecret { get; set; } public string ApiSecret { get; set; }
} }
public class FileJwtConfig
{
public string Authority { get; set; }
public string Audience { get; set; }
}
} }

View File

@ -25,8 +25,12 @@ namespace Ocelot.AcceptanceTests
{ {
switch (jsonObject["Provider"].Value<string>()) switch (jsonObject["Provider"].Value<string>())
{ {
//case "Jwt": case "Jwt":
// setting = new setting = new JwtConfig(
jsonObject["Authority"].Value<string>(),
jsonObject["Audience"].Value<string>());
break;
default: default:
setting = new IdentityServerConfig( setting = new IdentityServerConfig(
jsonObject["ProviderRootUrl"].Value<string>(), jsonObject["ProviderRootUrl"].Value<string>(),

View File

@ -31,17 +31,19 @@ namespace Ocelot.UnitTests.Authentication
_authenticationHandlerFactory = new AuthenticationHandlerFactory(_creator.Object); _authenticationHandlerFactory = new AuthenticationHandlerFactory(_creator.Object);
} }
[Fact] [Theory]
public void should_return_identity_server_access_token_handler() [InlineData("IdentityServer")]
[InlineData("Jwt")]
public void should_return_access_token_handler(string provider)
{ {
var authenticationOptions = new AuthenticationOptionsBuilder() var authenticationOptions = new AuthenticationOptionsBuilder()
.WithProvider("IdentityServer") .WithProvider(provider)
.Build(); .Build();
this.Given(x => x.GivenTheAuthenticationOptionsAre(authenticationOptions)) this.Given(x => x.GivenTheAuthenticationOptionsAre(authenticationOptions))
.And(x => x.GivenTheCreatorReturns()) .And(x => x.GivenTheCreatorReturns())
.When(x => x.WhenIGetFromTheFactory()) .When(x => x.WhenIGetFromTheFactory())
.Then(x => x.ThenTheHandlerIsReturned("IdentityServer")) .Then(x => x.ThenTheHandlerIsReturned(provider))
.BDDfy(); .BDDfy();
} }

View File

@ -20,36 +20,78 @@ namespace Ocelot.UnitTests.Configuration
_authOptionsCreator = new AuthenticationOptionsCreator(); _authOptionsCreator = new AuthenticationOptionsCreator();
} }
// [Fact] [Fact]
// public void should_return_auth_options() public void should_return_auth_options()
// { {
// var fileReRoute = new FileReRoute() var fileReRoute = new FileReRoute()
// { {
// AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
// { {
// Provider = "Geoff", Provider = "Geoff",
// ProviderRootUrl = "http://www.bbc.co.uk/", IdentityServerConfig = new FileIdentityServerConfig()
//ApiName = "Laura", {
// RequireHttps = true, ProviderRootUrl = "http://www.bbc.co.uk/",
//AllowedScopes = new List<string> {"cheese"}, ApiName = "Laura",
// ApiSecret = "secret" RequireHttps = true,
// } ApiSecret = "secret"
// }; },
AllowedScopes = new List<string> { "cheese" },
// var expected = new AuthenticationOptionsBuilder() }
// .WithProvider(fileReRoute.AuthenticationOptions?.Provider) };
// .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
// .WithApiName(fileReRoute.AuthenticationOptions?.ApiName)
// .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
// .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
// .WithApiSecret(fileReRoute.AuthenticationOptions?.ApiSecret)
// .Build();
// this.Given(x => x.GivenTheFollowing(fileReRoute)) var authenticationConfig = new IdentityServerConfigBuilder()
// .When(x => x.WhenICreateTheAuthenticationOptions()) .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ProviderRootUrl)
// .Then(x => x.ThenTheFollowingIsReturned(expected)) .WithApiName(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiName)
// .BDDfy(); .WithRequireHttps(fileReRoute.AuthenticationOptions.IdentityServerConfig.RequireHttps)
// } .WithApiSecret(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiSecret)
.Build();
var expected = new AuthenticationOptionsBuilder()
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
.WithConfig(authenticationConfig)
.Build();
this.Given(x => x.GivenTheFollowing(fileReRoute))
.When(x => x.WhenICreateTheAuthenticationOptions())
.Then(x => x.ThenTheFollowingIdentityServerConfigIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_return_Jwt_auth_options()
{
var fileReRoute = new FileReRoute()
{
AuthenticationOptions = new FileAuthenticationOptions
{
Provider = "Jwt",
JwtConfig = new FileJwtConfig()
{
Audience = "Audience",
Authority = "Authority"
},
AllowedScopes = new List<string> { "cheese" }
}
};
var authenticationConfig = new JwtConfigBuilder()
.WithAudience(fileReRoute.AuthenticationOptions?.JwtConfig?.Audience)
.WithAuthority(fileReRoute.AuthenticationOptions?.JwtConfig?.Authority)
.Build();
var expected = new AuthenticationOptionsBuilder()
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
.WithConfig(authenticationConfig)
.Build();
this.Given(x => x.GivenTheFollowing(fileReRoute))
.When(x => x.WhenICreateTheAuthenticationOptions())
.Then(x => x.ThenTheFollowingJwtConfigIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowing(FileReRoute fileReRoute) private void GivenTheFollowing(FileReRoute fileReRoute)
{ {
@ -61,14 +103,31 @@ namespace Ocelot.UnitTests.Configuration
_result = _authOptionsCreator.Create(_fileReRoute); _result = _authOptionsCreator.Create(_fileReRoute);
} }
//private void ThenTheFollowingIsReturned(AuthenticationOptions expected) private void ThenTheFollowingJwtConfigIsReturned(AuthenticationOptions expected)
//{ {
// _result.AllowedScopes.ShouldBe(expected.AllowedScopes); _result.AllowedScopes.ShouldBe(expected.AllowedScopes);
// _result.Provider.ShouldBe(expected.Provider); _result.Provider.ShouldBe(expected.Provider);
// _result.ProviderRootUrl.ShouldBe(expected.ProviderRootUrl);
// _result.RequireHttps.ShouldBe(expected.RequireHttps); var _resultSettings = _result.Config as JwtConfig;
// _result.ApiName.ShouldBe(expected.ApiName); var expectedSettngs = expected.Config as JwtConfig;
// _result.ApiSecret.ShouldBe(expected.ApiSecret);
//} _resultSettings.Audience.ShouldBe(expectedSettngs.Audience);
_resultSettings.Authority.ShouldBe(expectedSettngs.Authority);
}
private void ThenTheFollowingIdentityServerConfigIsReturned(AuthenticationOptions expected)
{
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
_result.Provider.ShouldBe(expected.Provider);
var _resultSettings = _result.Config as IdentityServerConfig;
var expectedSettngs = expected.Config as IdentityServerConfig;
_resultSettings.ProviderRootUrl.ShouldBe(expectedSettngs.ProviderRootUrl);
_resultSettings.RequireHttps.ShouldBe(expectedSettngs.RequireHttps);
_resultSettings.ApiName.ShouldBe(expectedSettngs.ApiName);
_resultSettings.ApiSecret.ShouldBe(expectedSettngs.ApiSecret);
}
} }
} }