mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Merge pull request #110 from sharpn/develop
Adding JWT authentication for use with auth0
This commit is contained in:
commit
50ee9e20d8
@ -6,6 +6,8 @@ using Ocelot.Responses;
|
|||||||
|
|
||||||
namespace Ocelot.Authentication.Handler.Creator
|
namespace Ocelot.Authentication.Handler.Creator
|
||||||
{
|
{
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
|
||||||
using AuthenticationOptions = Configuration.AuthenticationOptions;
|
using AuthenticationOptions = Configuration.AuthenticationOptions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -17,15 +19,31 @@ namespace Ocelot.Authentication.Handler.Creator
|
|||||||
{
|
{
|
||||||
var builder = app.New();
|
var builder = app.New();
|
||||||
|
|
||||||
builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
if (authOptions.Provider.ToLower() == "jwt")
|
||||||
{
|
{
|
||||||
Authority = authOptions.ProviderRootUrl,
|
var authenticationConfig = authOptions.Config as JwtConfig;
|
||||||
ApiName = authOptions.ApiName,
|
|
||||||
RequireHttpsMetadata = authOptions.RequireHttps,
|
builder.UseJwtBearerAuthentication(
|
||||||
AllowedScopes = authOptions.AllowedScopes,
|
new JwtBearerOptions()
|
||||||
SupportedTokens = SupportedTokens.Both,
|
{
|
||||||
ApiSecret = authOptions.ApiSecret
|
Authority = authenticationConfig.Authority,
|
||||||
});
|
Audience = authenticationConfig.Audience
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var authenticationConfig = authOptions.Config as IdentityServerConfig;
|
||||||
|
|
||||||
|
builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
||||||
|
{
|
||||||
|
Authority = authenticationConfig.ProviderRootUrl,
|
||||||
|
ApiName = authenticationConfig.ApiName,
|
||||||
|
RequireHttpsMetadata = authenticationConfig.RequireHttps,
|
||||||
|
AllowedScopes = authOptions.AllowedScopes,
|
||||||
|
SupportedTokens = SupportedTokens.Both,
|
||||||
|
ApiSecret = authenticationConfig.ApiSecret
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var authenticationNext = builder.Build();
|
var authenticationNext = builder.Build();
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
public enum SupportedAuthenticationProviders
|
public enum SupportedAuthenticationProviders
|
||||||
{
|
{
|
||||||
IdentityServer
|
IdentityServer,
|
||||||
|
Jwt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,24 +2,52 @@
|
|||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
public class AuthenticationOptions
|
public class AuthenticationOptions
|
||||||
{
|
{
|
||||||
public AuthenticationOptions(string provider, string providerRootUrl, string apiName, bool requireHttps, List<string> allowedScopes, string apiSecret)
|
public AuthenticationOptions(string provider, List<string> allowedScopes, IAuthenticationConfig config)
|
||||||
{
|
{
|
||||||
Provider = provider;
|
Provider = provider;
|
||||||
ProviderRootUrl = providerRootUrl;
|
AllowedScopes = allowedScopes;
|
||||||
ApiName = apiName;
|
Config = config;
|
||||||
RequireHttps = requireHttps;
|
|
||||||
AllowedScopes = allowedScopes;
|
|
||||||
ApiSecret = apiSecret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Provider { get; private set; }
|
public string Provider { get; private set; }
|
||||||
|
|
||||||
|
public List<string> AllowedScopes { get; private set; }
|
||||||
|
|
||||||
|
public IAuthenticationConfig Config { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityServerConfig : IAuthenticationConfig
|
||||||
|
{
|
||||||
|
public IdentityServerConfig(string providerRootUrl, string apiName, bool requireHttps, string apiSecret)
|
||||||
|
{
|
||||||
|
ProviderRootUrl = providerRootUrl;
|
||||||
|
ApiName = apiName;
|
||||||
|
RequireHttps = requireHttps;
|
||||||
|
ApiSecret = apiSecret;
|
||||||
|
}
|
||||||
|
|
||||||
public string ProviderRootUrl { get; private set; }
|
public string ProviderRootUrl { get; private set; }
|
||||||
public string ApiName { get; private set; }
|
public string ApiName { get; private set; }
|
||||||
public string ApiSecret { get; private set; }
|
public string ApiSecret { get; private set; }
|
||||||
public bool RequireHttps { get; private set; }
|
public bool RequireHttps { get; private set; }
|
||||||
public List<string> AllowedScopes { 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 {}
|
||||||
}
|
}
|
||||||
|
@ -6,51 +6,93 @@ namespace Ocelot.Configuration.Builder
|
|||||||
{
|
{
|
||||||
|
|
||||||
private string _provider;
|
private string _provider;
|
||||||
private string _providerRootUrl;
|
|
||||||
private string _apiName;
|
|
||||||
private string _apiSecret;
|
|
||||||
private bool _requireHttps;
|
|
||||||
private List<string> _allowedScopes;
|
private List<string> _allowedScopes;
|
||||||
|
|
||||||
|
private IAuthenticationConfig _identityServerConfig;
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithProvider(string provider)
|
public AuthenticationOptionsBuilder WithProvider(string provider)
|
||||||
{
|
{
|
||||||
_provider = provider;
|
_provider = provider;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithProviderRootUrl(string providerRootUrl)
|
|
||||||
{
|
|
||||||
_providerRootUrl = providerRootUrl;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithApiName(string apiName)
|
|
||||||
{
|
|
||||||
_apiName = apiName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithApiSecret(string apiSecret)
|
|
||||||
{
|
|
||||||
_apiSecret = apiSecret;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithRequireHttps(bool requireHttps)
|
|
||||||
{
|
|
||||||
_requireHttps = requireHttps;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
|
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
|
||||||
{
|
{
|
||||||
_allowedScopes = allowedScopes;
|
_allowedScopes = allowedScopes;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AuthenticationOptionsBuilder WithConfig(IAuthenticationConfig config)
|
||||||
|
{
|
||||||
|
_identityServerConfig = config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public AuthenticationOptions Build()
|
public AuthenticationOptions Build()
|
||||||
{
|
{
|
||||||
return new AuthenticationOptions(_provider, _providerRootUrl, _apiName, _requireHttps, _allowedScopes, _apiSecret);
|
return new AuthenticationOptions(_provider, _allowedScopes, _identityServerConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityServerConfigBuilder
|
||||||
|
{
|
||||||
|
private string _providerRootUrl;
|
||||||
|
private string _apiName;
|
||||||
|
private string _apiSecret;
|
||||||
|
private bool _requireHttps;
|
||||||
|
|
||||||
|
public IdentityServerConfigBuilder WithProviderRootUrl(string providerRootUrl)
|
||||||
|
{
|
||||||
|
_providerRootUrl = providerRootUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityServerConfigBuilder WithApiName(string apiName)
|
||||||
|
{
|
||||||
|
_apiName = apiName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityServerConfigBuilder WithApiSecret(string apiSecret)
|
||||||
|
{
|
||||||
|
_apiSecret = apiSecret;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityServerConfigBuilder WithRequireHttps(bool requireHttps)
|
||||||
|
{
|
||||||
|
_requireHttps = requireHttps;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityServerConfig Build()
|
||||||
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,14 +7,13 @@ namespace Ocelot.Configuration.Creator
|
|||||||
{
|
{
|
||||||
public AuthenticationOptions Create(FileReRoute fileReRoute)
|
public AuthenticationOptions Create(FileReRoute fileReRoute)
|
||||||
{
|
{
|
||||||
|
var authenticationConfig = new ConfigCreator().Create(fileReRoute.AuthenticationOptions);
|
||||||
|
|
||||||
return new AuthenticationOptionsBuilder()
|
return new AuthenticationOptionsBuilder()
|
||||||
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
||||||
.WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
|
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||||
.WithApiName(fileReRoute.AuthenticationOptions?.ApiName)
|
.WithConfig(authenticationConfig)
|
||||||
.WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
|
.Build();
|
||||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
|
||||||
.WithApiSecret(fileReRoute.AuthenticationOptions?.ApiSecret)
|
|
||||||
.Build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
35
src/Ocelot/Configuration/Creator/ConfigCreator.cs
Normal file
35
src/Ocelot/Configuration/Creator/ConfigCreator.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,14 +6,29 @@ namespace Ocelot.Configuration.File
|
|||||||
{
|
{
|
||||||
public FileAuthenticationOptions()
|
public FileAuthenticationOptions()
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>();
|
AllowedScopes = new List<string>();
|
||||||
|
IdentityServerConfig = new FileIdentityServerConfig();
|
||||||
|
JwtConfig = new FileJwtConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Provider { get; set; }
|
public string Provider { get; set; }
|
||||||
|
public List<string> AllowedScopes { get; set; }
|
||||||
|
public FileIdentityServerConfig IdentityServerConfig { get; set; }
|
||||||
|
public FileJwtConfig JwtConfig { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FileIdentityServerConfig
|
||||||
|
{
|
||||||
public string ProviderRootUrl { get; set; }
|
public string ProviderRootUrl { get; set; }
|
||||||
public string ApiName { get; set; }
|
public string ApiName { get; set; }
|
||||||
public bool RequireHttps { get; set; }
|
public bool RequireHttps { get; set; }
|
||||||
public List<string> AllowedScopes { 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; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ using Ocelot.ServiceDiscovery;
|
|||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
namespace Ocelot.Configuration.Repository
|
||||||
{
|
{
|
||||||
|
using Ocelot.AcceptanceTests;
|
||||||
|
|
||||||
public class ConsulOcelotConfigurationRepository : IOcelotConfigurationRepository
|
public class ConsulOcelotConfigurationRepository : IOcelotConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly ConsulClient _consul;
|
private readonly ConsulClient _consul;
|
||||||
@ -48,7 +50,9 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
var json = Encoding.UTF8.GetString(bytes);
|
var json = Encoding.UTF8.GetString(bytes);
|
||||||
|
|
||||||
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
var settings = new JsonSerializerSettings();
|
||||||
|
settings.Converters.Add(new AuthenticationConfigConverter());
|
||||||
|
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
|
||||||
|
|
||||||
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
||||||
}
|
}
|
||||||
|
59
src/Ocelot/JsonConverters/AuthenticationConfigConverter.cs
Normal file
59
src/Ocelot/JsonConverters/AuthenticationConfigConverter.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
|
||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
public class AuthenticationConfigConverter : JsonConverter
|
||||||
|
{
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
|
||||||
|
public override bool CanRead => true;
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Use default serialization.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
var jsonObject = JObject.Load(reader);
|
||||||
|
var setting = default(IAuthenticationConfig);
|
||||||
|
|
||||||
|
if (jsonObject["Provider"] != null)
|
||||||
|
{
|
||||||
|
switch (jsonObject["Provider"].Value<string>())
|
||||||
|
{
|
||||||
|
case "Jwt":
|
||||||
|
setting = new JwtConfig(
|
||||||
|
jsonObject["Authority"].Value<string>(),
|
||||||
|
jsonObject["Audience"].Value<string>());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
setting = new IdentityServerConfig(
|
||||||
|
jsonObject["ProviderRootUrl"].Value<string>(),
|
||||||
|
jsonObject["ApiName"].Value<string>(),
|
||||||
|
jsonObject["RequireHttps"].Value<bool>(),
|
||||||
|
jsonObject["ApiSecret"].Value<string>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setting = new IdentityServerConfig(string.Empty, string.Empty, false, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer.Populate(jsonObject.CreateReader(), setting);
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return objectType == typeof(IAuthenticationConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -37,237 +37,209 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_401_using_identity_server_access_token()
|
public void should_return_401_using_identity_server_access_token()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = _downstreamServicePath,
|
DownstreamPathTemplate = _downstreamServicePath,
|
||||||
DownstreamPort = _downstreamServicePort,
|
DownstreamPort = _downstreamServicePort,
|
||||||
DownstreamHost = _downstreamServiceHost,
|
DownstreamHost = _downstreamServiceHost,
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = _identityServerRootUrl,
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_401_using_identity_server_reference_token()
|
|
||||||
{
|
|
||||||
var configuration = new FileConfiguration
|
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
DownstreamPathTemplate = _downstreamServicePath,
|
|
||||||
DownstreamPort = _downstreamServicePort,
|
|
||||||
DownstreamHost = _downstreamServiceHost,
|
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
|
||||||
UpstreamPathTemplate = "/",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Reference))
|
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_using_identity_server()
|
public void should_return_response_200_using_identity_server()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = _downstreamServicePath,
|
DownstreamPathTemplate = _downstreamServicePath,
|
||||||
DownstreamPort = _downstreamServicePort,
|
DownstreamPort = _downstreamServicePort,
|
||||||
DownstreamHost = _downstreamServiceHost,
|
DownstreamHost = _downstreamServiceHost,
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = _identityServerRootUrl,
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_401_using_identity_server_with_token_requested_for_other_api()
|
public void should_return_response_401_using_identity_server_with_token_requested_for_other_api()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = _downstreamServicePath,
|
DownstreamPathTemplate = _downstreamServicePath,
|
||||||
DownstreamPort = _downstreamServicePort,
|
DownstreamPort = _downstreamServicePort,
|
||||||
DownstreamHost = _downstreamServiceHost,
|
DownstreamHost = _downstreamServiceHost,
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = _identityServerRootUrl,
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApi2(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveATokenForApi2(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_201_using_identity_server_access_token()
|
public void should_return_201_using_identity_server_access_token()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = _downstreamServicePath,
|
DownstreamPathTemplate = _downstreamServicePath,
|
||||||
DownstreamPort = _downstreamServicePort,
|
DownstreamPort = _downstreamServicePort,
|
||||||
DownstreamHost = _downstreamServiceHost,
|
DownstreamHost = _downstreamServiceHost,
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
|
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = _identityServerRootUrl,
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_201_using_identity_server_reference_token()
|
public void should_return_201_using_identity_server_reference_token()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = _downstreamServicePath,
|
DownstreamPathTemplate = _downstreamServicePath,
|
||||||
DownstreamPort = _downstreamServicePort,
|
DownstreamPort = _downstreamServicePort,
|
||||||
DownstreamHost = _downstreamServiceHost,
|
DownstreamHost = _downstreamServiceHost,
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = _identityServerRootUrl,
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Reference))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Reference))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||||
|
@ -31,191 +31,199 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_authorising_route()
|
public void should_return_response_200_authorising_route()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
DownstreamPort = 51876,
|
DownstreamPort = 51876,
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = "http://localhost:51888",
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
},
|
ApiSecret = "secret"
|
||||||
AddHeadersToRequest =
|
}
|
||||||
{
|
},
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
AddHeadersToRequest =
|
||||||
{"LocationId", "Claims[LocationId] > value"},
|
{
|
||||||
{"UserType", "Claims[sub] > value[0] > |"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
{"UserId", "Claims[sub] > value[1] > |"}
|
{"LocationId", "Claims[LocationId] > value"},
|
||||||
},
|
{"UserType", "Claims[sub] > value[0] > |"},
|
||||||
AddClaimsToRequest =
|
{"UserId", "Claims[sub] > value[1] > |"}
|
||||||
{
|
},
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
AddClaimsToRequest =
|
||||||
{"UserType", "Claims[sub] > value[0] > |"},
|
{
|
||||||
{"UserId", "Claims[sub] > value[1] > |"}
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
},
|
{"UserType", "Claims[sub] > value[0] > |"},
|
||||||
RouteClaimsRequirement =
|
{"UserId", "Claims[sub] > value[1] > |"}
|
||||||
{
|
},
|
||||||
{"UserType", "registered"}
|
RouteClaimsRequirement =
|
||||||
}
|
{
|
||||||
}
|
{"UserType", "registered"}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_403_authorising_route()
|
public void should_return_response_403_authorising_route()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
DownstreamPort = 51876,
|
DownstreamPort = 51876,
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
AllowedScopes = new List<string>(),
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = "http://localhost:51888",
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
},
|
ApiSecret = "secret"
|
||||||
AddHeadersToRequest =
|
}
|
||||||
{
|
},
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
AddHeadersToRequest =
|
||||||
{"LocationId", "Claims[LocationId] > value"},
|
{
|
||||||
{"UserType", "Claims[sub] > value[0] > |"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
{"UserId", "Claims[sub] > value[1] > |"}
|
{"LocationId", "Claims[LocationId] > value"},
|
||||||
},
|
{"UserType", "Claims[sub] > value[0] > |"},
|
||||||
AddClaimsToRequest =
|
{"UserId", "Claims[sub] > value[1] > |"}
|
||||||
{
|
},
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
AddClaimsToRequest =
|
||||||
{"UserId", "Claims[sub] > value[1] > |"}
|
{
|
||||||
},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
RouteClaimsRequirement =
|
{"UserId", "Claims[sub] > value[1] > |"}
|
||||||
{
|
},
|
||||||
{"UserType", "registered"}
|
RouteClaimsRequirement =
|
||||||
}
|
{
|
||||||
}
|
{"UserType", "registered"}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_using_identity_server_with_allowed_scope()
|
public void should_return_response_200_using_identity_server_with_allowed_scope()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
DownstreamPort = 51876,
|
DownstreamPort = 51876,
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>{ "api", "api.readOnly", "openid", "offline_access" },
|
AllowedScopes = new List<string>{ "api", "api.readOnly", "openid", "offline_access" },
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = "http://localhost:51888",
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_403_using_identity_server_with_scope_not_allowed()
|
public void should_return_response_403_using_identity_server_with_scope_not_allowed()
|
||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
DownstreamPort = 51876,
|
DownstreamPort = 51876,
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>{ "api", "openid", "offline_access" },
|
AllowedScopes = new List<string>{ "api", "openid", "offline_access" },
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = "http://localhost:51888",
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret"
|
ApiName = "api",
|
||||||
}
|
ApiSecret = "secret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||||
|
@ -33,63 +33,65 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_and_foward_claim_as_header()
|
public void should_return_response_200_and_foward_claim_as_header()
|
||||||
{
|
{
|
||||||
var user = new TestUser()
|
var user = new TestUser()
|
||||||
{
|
{
|
||||||
Username = "test",
|
Username = "test",
|
||||||
Password = "test",
|
Password = "test",
|
||||||
SubjectId = "registered|1231231",
|
SubjectId = "registered|1231231",
|
||||||
Claims = new List<Claim>
|
Claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new Claim("CustomerId", "123"),
|
new Claim("CustomerId", "123"),
|
||||||
new Claim("LocationId", "1")
|
new Claim("LocationId", "1")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
DownstreamPort = 52876,
|
DownstreamPort = 52876,
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>
|
AllowedScopes = new List<string>
|
||||||
{
|
{
|
||||||
"openid", "offline_access", "api"
|
"openid", "offline_access", "api"
|
||||||
},
|
},
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = "http://localhost:52888",
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = "http://localhost:52888",
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret",
|
ApiName = "api",
|
||||||
},
|
ApiSecret = "secret"
|
||||||
AddHeadersToRequest =
|
}
|
||||||
{
|
},
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
AddHeadersToRequest =
|
||||||
{"LocationId", "Claims[LocationId] > value"},
|
{
|
||||||
{"UserType", "Claims[sub] > value[0] > |"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
{"UserId", "Claims[sub] > value[1] > |"}
|
{"LocationId", "Claims[LocationId] > value"},
|
||||||
}
|
{"UserType", "Claims[sub] > value[0] > |"},
|
||||||
}
|
{"UserId", "Claims[sub] > value[1] > |"}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:52888", "api", AccessTokenType.Jwt, user))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:52888", "api", AccessTokenType.Jwt, user))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:52876", 200))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:52876", 200))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:52888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:52888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("CustomerId: 123 LocationId: 1 UserType: registered UserId: 1231231"))
|
.And(x => _steps.ThenTheResponseBodyShouldBe("CustomerId: 123 LocationId: 1 UserType: registered UserId: 1231231"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
||||||
|
@ -33,63 +33,65 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_and_foward_claim_as_query_string()
|
public void should_return_response_200_and_foward_claim_as_query_string()
|
||||||
{
|
{
|
||||||
var user = new TestUser()
|
var user = new TestUser()
|
||||||
{
|
{
|
||||||
Username = "test",
|
Username = "test",
|
||||||
Password = "test",
|
Password = "test",
|
||||||
SubjectId = "registered|1231231",
|
SubjectId = "registered|1231231",
|
||||||
Claims = new List<Claim>
|
Claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new Claim("CustomerId", "123"),
|
new Claim("CustomerId", "123"),
|
||||||
new Claim("LocationId", "1")
|
new Claim("LocationId", "1")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/",
|
DownstreamPathTemplate = "/",
|
||||||
DownstreamPort = 57876,
|
DownstreamPort = 57876,
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>
|
AllowedScopes = new List<string>
|
||||||
{
|
{
|
||||||
"openid", "offline_access", "api"
|
"openid", "offline_access", "api"
|
||||||
},
|
},
|
||||||
Provider = "IdentityServer",
|
Provider = "IdentityServer",
|
||||||
ProviderRootUrl = "http://localhost:57888",
|
IdentityServerConfig = new FileIdentityServerConfig{
|
||||||
RequireHttps = false,
|
ProviderRootUrl = "http://localhost:57888",
|
||||||
ApiName = "api",
|
RequireHttps = false,
|
||||||
ApiSecret = "secret",
|
ApiName = "api",
|
||||||
},
|
ApiSecret = "secret"
|
||||||
AddQueriesToRequest =
|
}
|
||||||
{
|
},
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
AddQueriesToRequest =
|
||||||
{"LocationId", "Claims[LocationId] > value"},
|
{
|
||||||
{"UserType", "Claims[sub] > value[0] > |"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
{"UserId", "Claims[sub] > value[1] > |"}
|
{"LocationId", "Claims[LocationId] > value"},
|
||||||
}
|
{"UserType", "Claims[sub] > value[0] > |"},
|
||||||
}
|
{"UserId", "Claims[sub] > value[1] > |"}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:57888", "api", AccessTokenType.Jwt, user))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:57888", "api", AccessTokenType.Jwt, user))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:57876", 200))
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:57876", 200))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:57888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:57888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
.And(x => _steps.GivenIHaveAddedATokenToMyRequest())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("CustomerId: 123 LocationId: 1 UserType: registered UserId: 1231231"))
|
.And(x => _steps.ThenTheResponseBodyShouldBe("CustomerId: 123 LocationId: 1 UserType: registered UserId: 1231231"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
||||||
|
@ -29,7 +29,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_with_simple_url()
|
public void should_return_response_200_with_simple_url()
|
||||||
{
|
{
|
||||||
@ -105,7 +104,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var json = reader.ReadToEnd();
|
var json = reader.ReadToEnd();
|
||||||
|
|
||||||
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
var settings = new JsonSerializerSettings();
|
||||||
|
settings.Converters.Add(new AuthenticationConfigConverter());
|
||||||
|
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
|
||||||
|
|
||||||
var response = JsonConvert.SerializeObject(true);
|
var response = JsonConvert.SerializeObject(true);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,26 +28,68 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
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 authenticationConfig = new IdentityServerConfigBuilder()
|
||||||
|
.WithProviderRootUrl(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ProviderRootUrl)
|
||||||
|
.WithApiName(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiName)
|
||||||
|
.WithRequireHttps(fileReRoute.AuthenticationOptions.IdentityServerConfig.RequireHttps)
|
||||||
|
.WithApiSecret(fileReRoute.AuthenticationOptions?.IdentityServerConfig?.ApiSecret)
|
||||||
|
.Build();
|
||||||
|
|
||||||
var expected = new AuthenticationOptionsBuilder()
|
var expected = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
|
||||||
.WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
|
|
||||||
.WithApiName(fileReRoute.AuthenticationOptions?.ApiName)
|
|
||||||
.WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
|
|
||||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||||
.WithApiSecret(fileReRoute.AuthenticationOptions?.ApiSecret)
|
.WithConfig(authenticationConfig)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
.When(x => x.WhenICreateTheAuthenticationOptions())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
.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();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,6 +18,10 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
namespace Ocelot.UnitTests.Configuration
|
||||||
{
|
{
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
using Ocelot.UnitTests.TestData;
|
||||||
|
|
||||||
public class FileConfigurationCreatorTests
|
public class FileConfigurationCreatorTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IOptions<FileConfiguration>> _fileConfig;
|
private readonly Mock<IOptions<FileConfiguration>> _fileConfig;
|
||||||
@ -440,20 +444,18 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void should_create_with_headers_to_extract()
|
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
||||||
|
public void should_create_with_headers_to_extract(string provider, IAuthenticationConfig config, FileConfiguration fileConfig)
|
||||||
{
|
{
|
||||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||||
.WithIsAuthenticated(true)
|
.WithIsAuthenticated(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var authenticationOptions = new AuthenticationOptionsBuilder()
|
var authenticationOptions = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider("IdentityServer")
|
.WithProvider(provider)
|
||||||
.WithProviderRootUrl("http://localhost:51888")
|
|
||||||
.WithRequireHttps(false)
|
|
||||||
.WithApiSecret("secret")
|
|
||||||
.WithApiName("api")
|
|
||||||
.WithAllowedScopes(new List<string>())
|
.WithAllowedScopes(new List<string>())
|
||||||
|
.WithConfig(config)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var expected = new List<ReRoute>
|
var expected = new List<ReRoute>
|
||||||
@ -470,59 +472,32 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.Build()
|
.Build()
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
this.Given(x => x.GivenTheConfigIs(fileConfig))
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
UpstreamPathTemplate = "/api/products/{productId}",
|
|
||||||
DownstreamPathTemplate = "/products/{productId}",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
ReRouteIsCaseSensitive = true,
|
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes= new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName= "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
},
|
|
||||||
AddHeadersToRequest =
|
|
||||||
{
|
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.And(x => x.GivenTheConfigIsValid())
|
.And(x => x.GivenTheConfigIsValid())
|
||||||
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
|
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
|
||||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||||
.And(x => x.GivenTheClaimsToThingCreatorReturns(new List<ClaimToThing>{new ClaimToThing("CustomerId", "CustomerId", "", 0)}))
|
.And(x => x.GivenTheClaimsToThingCreatorReturns(new List<ClaimToThing> { new ClaimToThing("CustomerId", "CustomerId", "", 0) }))
|
||||||
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
||||||
.When(x => x.WhenICreateTheConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||||
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(provider, expected))
|
||||||
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void should_create_with_authentication_properties()
|
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
||||||
|
public void should_create_with_authentication_properties(string provider, IAuthenticationConfig config, FileConfiguration fileConfig)
|
||||||
{
|
{
|
||||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||||
.WithIsAuthenticated(true)
|
.WithIsAuthenticated(true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var authenticationOptions = new AuthenticationOptionsBuilder()
|
var authenticationOptions = new AuthenticationOptionsBuilder()
|
||||||
.WithProvider("IdentityServer")
|
.WithProvider(provider)
|
||||||
.WithProviderRootUrl("http://localhost:51888")
|
.WithAllowedScopes(new List<string>())
|
||||||
.WithRequireHttps(false)
|
.WithConfig(config)
|
||||||
.WithApiSecret("secret")
|
.Build();
|
||||||
.WithApiName("api")
|
|
||||||
.WithAllowedScopes(new List<string>())
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var expected = new List<ReRoute>
|
var expected = new List<ReRoute>
|
||||||
{
|
{
|
||||||
@ -534,35 +509,14 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.Build()
|
.Build()
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
this.Given(x => x.GivenTheConfigIs(fileConfig))
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
UpstreamPathTemplate = "/api/products/{productId}",
|
|
||||||
DownstreamPathTemplate = "/products/{productId}",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
ReRouteIsCaseSensitive = true,
|
|
||||||
AuthenticationOptions = new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName= "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.And(x => x.GivenTheConfigIsValid())
|
.And(x => x.GivenTheConfigIsValid())
|
||||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||||
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
|
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
|
||||||
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
.And(x => x.GivenTheLoadBalancerFactoryReturns())
|
||||||
.When(x => x.WhenICreateTheConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||||
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(provider, expected))
|
||||||
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
@ -633,7 +587,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes)
|
private void ThenTheAuthenticationOptionsAre(string provider, List<ReRoute> expectedReRoutes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||||
{
|
{
|
||||||
@ -642,11 +596,25 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
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);
|
|
||||||
result.ApiName.ShouldBe(expected.ApiName);
|
|
||||||
result.ApiSecret.ShouldBe(expected.ApiSecret);
|
|
||||||
|
|
||||||
|
if (provider.ToLower() == "identityserver")
|
||||||
|
{
|
||||||
|
var config = result.Config as IdentityServerConfig;
|
||||||
|
var expectedConfig = expected.Config as IdentityServerConfig;
|
||||||
|
|
||||||
|
config.ProviderRootUrl.ShouldBe(expectedConfig.ProviderRootUrl);
|
||||||
|
config.RequireHttps.ShouldBe(expectedConfig.RequireHttps);
|
||||||
|
config.ApiName.ShouldBe(expectedConfig.ApiName);
|
||||||
|
config.ApiSecret.ShouldBe(expectedConfig.ApiSecret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var config = result.Config as JwtConfig;
|
||||||
|
var expectedConfig = expected.Config as JwtConfig;
|
||||||
|
|
||||||
|
config.Audience.ShouldBe(expectedConfig.Audience);
|
||||||
|
config.Authority.ShouldBe(expectedConfig.Authority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
namespace Ocelot.UnitTests.TestData
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
|
public class AuthenticationConfigTestData
|
||||||
|
{
|
||||||
|
public static IEnumerable<object[]> GetAuthenticationData()
|
||||||
|
{
|
||||||
|
yield return new object[]
|
||||||
|
{
|
||||||
|
"IdentityServer",
|
||||||
|
new IdentityServerConfigBuilder()
|
||||||
|
.WithRequireHttps(true)
|
||||||
|
.WithApiName("test")
|
||||||
|
.WithApiSecret("test")
|
||||||
|
.WithProviderRootUrl("test")
|
||||||
|
.Build(),
|
||||||
|
new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
UpstreamPathTemplate = "/api/products/{productId}",
|
||||||
|
DownstreamPathTemplate = "/products/{productId}",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
ReRouteIsCaseSensitive = true,
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AllowedScopes = new List<string>(),
|
||||||
|
Provider = "IdentityServer",
|
||||||
|
IdentityServerConfig = new FileIdentityServerConfig
|
||||||
|
{
|
||||||
|
ProviderRootUrl = "http://localhost:51888",
|
||||||
|
RequireHttps = false,
|
||||||
|
ApiName = "api",
|
||||||
|
ApiSecret = "secret"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
AddHeadersToRequest =
|
||||||
|
{
|
||||||
|
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
yield return new object[]
|
||||||
|
{
|
||||||
|
"Jwt",
|
||||||
|
new JwtConfigBuilder()
|
||||||
|
.WithAudience("a")
|
||||||
|
.WithAuthority("au")
|
||||||
|
.Build(),
|
||||||
|
new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
UpstreamPathTemplate = "/api/products/{productId}",
|
||||||
|
DownstreamPathTemplate = "/products/{productId}",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
ReRouteIsCaseSensitive = true,
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AllowedScopes = new List<string>(),
|
||||||
|
Provider = "IdentityServer",
|
||||||
|
JwtConfig = new FileJwtConfig
|
||||||
|
{
|
||||||
|
Audience = "a",
|
||||||
|
Authority = "au"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
AddHeadersToRequest =
|
||||||
|
{
|
||||||
|
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user