mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
test passing with authentication being provided by the user and mapped to the re route in config
This commit is contained in:
parent
967f0f7128
commit
3f2af85969
@ -1,4 +1,5 @@
|
|||||||
using System;
|
/*
|
||||||
|
using System;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
@ -57,3 +58,4 @@ namespace Ocelot.Authentication.JsonConverters
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -2,52 +2,13 @@
|
|||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
public class AuthenticationOptions
|
public class AuthenticationOptions
|
||||||
{
|
{
|
||||||
public AuthenticationOptions(string provider, List<string> allowedScopes, IAuthenticationConfig config)
|
public AuthenticationOptions(List<string> allowedScopes)
|
||||||
{
|
{
|
||||||
Provider = provider;
|
|
||||||
AllowedScopes = allowedScopes;
|
AllowedScopes = allowedScopes;
|
||||||
Config = config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Provider { get; private set; }
|
|
||||||
|
|
||||||
public List<string> AllowedScopes { 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 ApiName { get; private set; }
|
|
||||||
public string ApiSecret { 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 {}
|
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,7 @@ namespace Ocelot.Configuration.Builder
|
|||||||
{
|
{
|
||||||
public class AuthenticationOptionsBuilder
|
public class AuthenticationOptionsBuilder
|
||||||
{
|
{
|
||||||
|
private List<string> _allowedScopes = new List<string>();
|
||||||
private string _provider;
|
|
||||||
|
|
||||||
private List<string> _allowedScopes;
|
|
||||||
|
|
||||||
private IAuthenticationConfig _identityServerConfig;
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithProvider(string provider)
|
|
||||||
{
|
|
||||||
_provider = provider;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
|
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
|
||||||
{
|
{
|
||||||
@ -23,76 +12,9 @@ namespace Ocelot.Configuration.Builder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationOptionsBuilder WithConfig(IAuthenticationConfig config)
|
|
||||||
{
|
|
||||||
_identityServerConfig = config;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptions Build()
|
public AuthenticationOptions Build()
|
||||||
{
|
{
|
||||||
return new AuthenticationOptions(_provider, _allowedScopes, _identityServerConfig);
|
return new AuthenticationOptions(_allowedScopes);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,38 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Creator.Configuration;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
namespace Ocelot.Configuration.Creator
|
||||||
{
|
{
|
||||||
public class AuthenticationOptionsCreator : IAuthenticationOptionsCreator
|
public class AuthenticationOptionsCreator : IAuthenticationOptionsCreator
|
||||||
{
|
{
|
||||||
private readonly IAuthenticationProviderConfigCreator _creator;
|
public AuthenticationOptions Create(FileReRoute reRoute)
|
||||||
|
|
||||||
public AuthenticationOptionsCreator(IAuthenticationProviderConfigCreator creator)
|
|
||||||
{
|
{
|
||||||
_creator = creator;
|
return new AuthenticationOptions(reRoute.AuthenticationOptions.AllowedScopes);
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationOptions Create(FileReRoute reRoute, List<FileAuthenticationOptions> authOptions)
|
|
||||||
{
|
|
||||||
//todo - loop is crap..
|
|
||||||
foreach(var authOption in authOptions)
|
|
||||||
{
|
|
||||||
if(reRoute.AuthenticationProviderKey == authOption.AuthenticationProviderKey)
|
|
||||||
{
|
|
||||||
var authenticationConfig = _creator.Create(authOption);
|
|
||||||
|
|
||||||
return new AuthenticationOptionsBuilder()
|
|
||||||
.WithProvider(authOption.Provider)
|
|
||||||
.WithAllowedScopes(authOption.AllowedScopes)
|
|
||||||
.WithConfig(authenticationConfig)
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo - should not return null?
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using Ocelot.Creator.Configuration;
|
/*using Ocelot.Creator.Configuration;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
namespace Ocelot.Configuration.Creator
|
||||||
{
|
{
|
||||||
@ -34,4 +34,4 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithRequireHttps(authenticationOptions.IdentityServerConfig.RequireHttps).Build();
|
.WithRequireHttps(authenticationOptions.IdentityServerConfig.RequireHttps).Build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
@ -92,7 +92,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
private async Task<IOcelotConfiguration> SetUpConfiguration(FileConfiguration fileConfiguration)
|
private async Task<IOcelotConfiguration> SetUpConfiguration(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var response = _configurationValidator.IsValid(fileConfiguration);
|
var response = await _configurationValidator.IsValid(fileConfiguration);
|
||||||
|
|
||||||
if (response.Data.IsError)
|
if (response.Data.IsError)
|
||||||
{
|
{
|
||||||
@ -110,14 +110,14 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
foreach (var reRoute in fileConfiguration.ReRoutes)
|
foreach (var reRoute in fileConfiguration.ReRoutes)
|
||||||
{
|
{
|
||||||
var ocelotReRoute = await SetUpReRoute(reRoute, fileConfiguration.GlobalConfiguration, fileConfiguration.AuthenticationOptions);
|
var ocelotReRoute = await SetUpReRoute(reRoute, fileConfiguration.GlobalConfiguration);
|
||||||
reRoutes.Add(ocelotReRoute);
|
reRoutes.Add(ocelotReRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OcelotConfiguration(reRoutes, fileConfiguration.GlobalConfiguration.AdministrationPath);
|
return new OcelotConfiguration(reRoutes, fileConfiguration.GlobalConfiguration.AdministrationPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, List<FileAuthenticationOptions> authOptions)
|
private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
|
||||||
{
|
{
|
||||||
var fileReRouteOptions = _fileReRouteOptionsCreator.Create(fileReRoute);
|
var fileReRouteOptions = _fileReRouteOptionsCreator.Create(fileReRoute);
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileReRoute, globalConfiguration);
|
var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileReRoute, globalConfiguration);
|
||||||
|
|
||||||
var authOptionsForRoute = _authOptionsCreator.Create(fileReRoute, authOptions);
|
var authOptionsForRoute = _authOptionsCreator.Create(fileReRoute);
|
||||||
|
|
||||||
var claimsToHeaders = _claimsToThingCreator.Create(fileReRoute.AddHeadersToRequest);
|
var claimsToHeaders = _claimsToThingCreator.Create(fileReRoute.AddHeadersToRequest);
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithQosOptions(qosOptions)
|
.WithQosOptions(qosOptions)
|
||||||
.WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
|
.WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
|
||||||
.WithRateLimitOptions(rateLimitOption)
|
.WithRateLimitOptions(rateLimitOption)
|
||||||
.WithAuthenticationProviderKey(fileReRoute.AuthenticationProviderKey)
|
.WithAuthenticationProviderKey(fileReRoute.AuthenticationOptions.AuthenticationProviderKey)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
await SetupLoadBalancer(reRoute);
|
await SetupLoadBalancer(reRoute);
|
||||||
|
@ -5,6 +5,6 @@ namespace Ocelot.Configuration.Creator
|
|||||||
{
|
{
|
||||||
public interface IAuthenticationOptionsCreator
|
public interface IAuthenticationOptionsCreator
|
||||||
{
|
{
|
||||||
AuthenticationOptions Create(FileReRoute reRoute, List<FileAuthenticationOptions> authOptions);
|
AuthenticationOptions Create(FileReRoute reRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
private bool IsAuthenticated(FileReRoute fileReRoute)
|
private bool IsAuthenticated(FileReRoute fileReRoute)
|
||||||
{
|
{
|
||||||
return !string.IsNullOrEmpty(fileReRoute.AuthenticationProviderKey);
|
return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.AuthenticationProviderKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsAuthorised(FileReRoute fileReRoute)
|
private bool IsAuthorised(FileReRoute fileReRoute)
|
||||||
|
@ -7,14 +7,9 @@ namespace Ocelot.Configuration.File
|
|||||||
public FileAuthenticationOptions()
|
public FileAuthenticationOptions()
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>();
|
AllowedScopes = new List<string>();
|
||||||
IdentityServerConfig = new FileIdentityServerConfig();
|
|
||||||
JwtConfig = new FileJwtConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string AuthenticationProviderKey {get; set;}
|
public string AuthenticationProviderKey {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 FileJwtConfig JwtConfig { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,9 @@ namespace Ocelot.Configuration.File
|
|||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>();
|
ReRoutes = new List<FileReRoute>();
|
||||||
GlobalConfiguration = new FileGlobalConfiguration();
|
GlobalConfiguration = new FileGlobalConfiguration();
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FileReRoute> ReRoutes { get; set; }
|
public List<FileReRoute> ReRoutes { get; set; }
|
||||||
public FileGlobalConfiguration GlobalConfiguration { get; set; }
|
public FileGlobalConfiguration GlobalConfiguration { get; set; }
|
||||||
public List<FileAuthenticationOptions> AuthenticationOptions { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace Ocelot.Configuration.File
|
|||||||
FileCacheOptions = new FileCacheOptions();
|
FileCacheOptions = new FileCacheOptions();
|
||||||
QoSOptions = new FileQoSOptions();
|
QoSOptions = new FileQoSOptions();
|
||||||
RateLimitOptions = new FileRateLimitRule();
|
RateLimitOptions = new FileRateLimitRule();
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DownstreamPathTemplate { get; set; }
|
public string DownstreamPathTemplate { get; set; }
|
||||||
@ -33,6 +34,6 @@ namespace Ocelot.Configuration.File
|
|||||||
public FileQoSOptions QoSOptions { get; set; }
|
public FileQoSOptions QoSOptions { get; set; }
|
||||||
public string LoadBalancer {get;set;}
|
public string LoadBalancer {get;set;}
|
||||||
public FileRateLimitRule RateLimitOptions { get; set; }
|
public FileRateLimitRule RateLimitOptions { get; set; }
|
||||||
public string AuthenticationProviderKey {get; set;}
|
public FileAuthenticationOptions AuthenticationOptions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,8 +3,6 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Ocelot.Authentication.JsonConverters;
|
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
|
|
||||||
@ -49,9 +47,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
var json = Encoding.UTF8.GetString(bytes);
|
var json = Encoding.UTF8.GetString(bytes);
|
||||||
|
|
||||||
var settings = new JsonSerializerSettings();
|
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
||||||
settings.Converters.Add(new AuthenticationConfigConverter());
|
|
||||||
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
|
|
||||||
|
|
||||||
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Ocelot.Authentication.Handler;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
@ -10,7 +10,14 @@ namespace Ocelot.Configuration.Validator
|
|||||||
{
|
{
|
||||||
public class FileConfigurationValidator : IConfigurationValidator
|
public class FileConfigurationValidator : IConfigurationValidator
|
||||||
{
|
{
|
||||||
public Response<ConfigurationValidationResult> IsValid(FileConfiguration configuration)
|
private readonly IAuthenticationSchemeProvider _provider;
|
||||||
|
|
||||||
|
public FileConfigurationValidator(IAuthenticationSchemeProvider provider)
|
||||||
|
{
|
||||||
|
_provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Response<ConfigurationValidationResult>> IsValid(FileConfiguration configuration)
|
||||||
{
|
{
|
||||||
var result = CheckForDuplicateReRoutes(configuration);
|
var result = CheckForDuplicateReRoutes(configuration);
|
||||||
|
|
||||||
@ -19,7 +26,7 @@ namespace Ocelot.Configuration.Validator
|
|||||||
return new OkResponse<ConfigurationValidationResult>(result);
|
return new OkResponse<ConfigurationValidationResult>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CheckForUnsupportedAuthenticationProviders(configuration);
|
result = await CheckForUnsupportedAuthenticationProviders(configuration);
|
||||||
|
|
||||||
if (result.IsError)
|
if (result.IsError)
|
||||||
{
|
{
|
||||||
@ -42,38 +49,27 @@ namespace Ocelot.Configuration.Validator
|
|||||||
return new OkResponse<ConfigurationValidationResult>(result);
|
return new OkResponse<ConfigurationValidationResult>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigurationValidationResult CheckForUnsupportedAuthenticationProviders(FileConfiguration configuration)
|
private async Task<ConfigurationValidationResult> CheckForUnsupportedAuthenticationProviders(FileConfiguration configuration)
|
||||||
{
|
{
|
||||||
var errors = new List<Error>();
|
var errors = new List<Error>();
|
||||||
|
|
||||||
//todo - these loops break seperation of concerns...unit tests should fail also..
|
|
||||||
foreach(var authProvider in configuration.AuthenticationOptions)
|
|
||||||
{
|
|
||||||
if (IsSupportedAuthenticationProvider(authProvider.Provider))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var error = new UnsupportedAuthenticationProviderError($"{authProvider.Provider} is unsupported authentication provider");
|
|
||||||
errors.Add(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var reRoute in configuration.ReRoutes)
|
foreach (var reRoute in configuration.ReRoutes)
|
||||||
{
|
{
|
||||||
var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationProviderKey);
|
var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions.AuthenticationProviderKey);
|
||||||
|
|
||||||
if (!isAuthenticated)
|
if (!isAuthenticated)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo is this correct?
|
var data = await _provider.GetAllSchemesAsync();
|
||||||
if(configuration.AuthenticationOptions.Exists(x => x.AuthenticationProviderKey == reRoute.AuthenticationProviderKey))
|
var schemes = data.ToList();
|
||||||
|
if (schemes.Any(x => x.Name == reRoute.AuthenticationOptions.AuthenticationProviderKey))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationProviderKey} is unsupported authentication provider, upstream template is {reRoute.UpstreamPathTemplate}, upstream method is {reRoute.UpstreamHttpMethod}");
|
var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationOptions.AuthenticationProviderKey} is unsupported authentication provider, upstream template is {reRoute.UpstreamPathTemplate}, upstream method is {reRoute.UpstreamHttpMethod}");
|
||||||
errors.Add(error);
|
errors.Add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,13 +78,6 @@ namespace Ocelot.Configuration.Validator
|
|||||||
: new ConfigurationValidationResult(false);
|
: new ConfigurationValidationResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSupportedAuthenticationProvider(string provider)
|
|
||||||
{
|
|
||||||
SupportedAuthenticationProviders supportedProvider;
|
|
||||||
|
|
||||||
return Enum.TryParse(provider, true, out supportedProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration)
|
private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration)
|
||||||
{
|
{
|
||||||
var errors = new List<Error>();
|
var errors = new List<Error>();
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
using Ocelot.Configuration.File;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Validator
|
namespace Ocelot.Configuration.Validator
|
||||||
{
|
{
|
||||||
public interface IConfigurationValidator
|
public interface IConfigurationValidator
|
||||||
{
|
{
|
||||||
Response<ConfigurationValidationResult> IsValid(FileConfiguration configuration);
|
Task<Response<ConfigurationValidationResult>> IsValid(FileConfiguration configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Ocelot.Configuration;
|
/*using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
namespace Ocelot.Creator.Configuration
|
namespace Ocelot.Creator.Configuration
|
||||||
@ -7,4 +7,4 @@ namespace Ocelot.Creator.Configuration
|
|||||||
{
|
{
|
||||||
IAuthenticationConfig Create(FileAuthenticationOptions authenticationOptions);
|
IAuthenticationConfig Create(FileAuthenticationOptions authenticationOptions);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
@ -42,15 +42,10 @@ using System.Net.Http;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Creator.Configuration;
|
|
||||||
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
||||||
using System.IO;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
@ -77,7 +72,6 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
services.Configure<FileConfiguration>(configurationRoot);
|
services.Configure<FileConfiguration>(configurationRoot);
|
||||||
services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
||||||
services.TryAddSingleton<IAuthenticationProviderConfigCreator, AuthenticationProviderConfigCreator>();
|
|
||||||
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
||||||
services.TryAddSingleton<IConfigurationValidator, FileConfigurationValidator>();
|
services.TryAddSingleton<IConfigurationValidator, FileConfigurationValidator>();
|
||||||
services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
||||||
@ -149,38 +143,6 @@ namespace Ocelot.DependencyInjection
|
|||||||
services.AddIdentityServer(identityServerConfiguration, configurationRoot);
|
services.AddIdentityServer(identityServerConfiguration, configurationRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo - this means we need to break auth providers into there own section in the config
|
|
||||||
//then join onto them from reroutes based on a key
|
|
||||||
var data = File.ReadAllText("configuration.json");
|
|
||||||
var config = JsonConvert.DeserializeObject<FileConfiguration>(data);
|
|
||||||
|
|
||||||
foreach(var authOptions in config.AuthenticationOptions)
|
|
||||||
{
|
|
||||||
if(authOptions.Provider.ToLower() == "identityserver")
|
|
||||||
{
|
|
||||||
Action<IdentityServerAuthenticationOptions> options = o =>
|
|
||||||
{
|
|
||||||
o.Authority = authOptions.IdentityServerConfig.ProviderRootUrl;
|
|
||||||
o.ApiName = authOptions.IdentityServerConfig.ApiName;
|
|
||||||
o.RequireHttpsMetadata = authOptions.IdentityServerConfig.RequireHttps;
|
|
||||||
o.SupportedTokens = SupportedTokens.Both;
|
|
||||||
o.ApiSecret = authOptions.IdentityServerConfig.ApiSecret;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.AddAuthentication()
|
|
||||||
.AddIdentityServerAuthentication(authOptions.AuthenticationProviderKey, options);
|
|
||||||
}
|
|
||||||
else if (authOptions.Provider.ToLower() == "jwt")
|
|
||||||
{
|
|
||||||
services.AddAuthentication()
|
|
||||||
.AddJwtBearer(x =>
|
|
||||||
{
|
|
||||||
x.Authority = authOptions.JwtConfig.Authority;
|
|
||||||
x.Audience = authOptions.JwtConfig.Audience;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.0.2" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
@ -42,7 +42,7 @@
|
|||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.1" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
<PackageReference Include="Polly" Version="5.3.1" />
|
<PackageReference Include="Polly" Version="5.3.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.0.1" />
|
<PackageReference Include="IdentityServer4" Version="2.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -14,7 +15,6 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
namespace Ocelot.AcceptanceTests
|
||||||
{
|
{
|
||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Test;
|
using IdentityServer4.Test;
|
||||||
|
|
||||||
public class AuthenticationTests : IDisposable
|
public class AuthenticationTests : IDisposable
|
||||||
@ -28,10 +28,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private int _downstreamServicePort = 51876;
|
private int _downstreamServicePort = 51876;
|
||||||
private string _downstreamServiceScheme = "http";
|
private string _downstreamServiceScheme = "http";
|
||||||
private string _downstreamServiceUrl = "http://localhost:51876";
|
private string _downstreamServiceUrl = "http://localhost:51876";
|
||||||
|
private readonly Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
|
||||||
public AuthenticationTests()
|
public AuthenticationTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -49,30 +58,18 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
},
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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(_options, "Test"))
|
||||||
.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))
|
||||||
@ -94,31 +91,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
},
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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(_options, "Test"))
|
||||||
.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))
|
||||||
@ -141,31 +126,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
},
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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(_options, "Test"))
|
||||||
.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))
|
||||||
@ -187,31 +160,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
}
|
|
||||||
},
|
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
{
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
},
|
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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(_options, "Test"))
|
||||||
.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("/"))
|
||||||
@ -234,31 +195,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Post" },
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig{
|
|
||||||
ProviderRootUrl = _identityServerRootUrl,
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
},
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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(_options, "Test"))
|
||||||
.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("/"))
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -22,10 +23,20 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private IWebHost _servicebuilder;
|
private IWebHost _servicebuilder;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:51888";
|
||||||
|
|
||||||
public AuthorisationTests()
|
public AuthorisationTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -33,7 +44,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
/* AuthenticationOptions = new List<FileAuthenticationOptions>
|
||||||
{
|
{
|
||||||
new FileAuthenticationOptions
|
new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
@ -47,7 +58,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -58,7 +69,10 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
@ -84,7 +98,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.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(_options, "Test"))
|
||||||
.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))
|
||||||
@ -97,7 +111,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
/* AuthenticationOptions = new List<FileAuthenticationOptions>
|
||||||
{
|
{
|
||||||
new FileAuthenticationOptions
|
new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
@ -111,7 +125,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -122,7 +136,10 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
@ -147,7 +164,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.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(_options, "Test"))
|
||||||
.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))
|
||||||
@ -159,7 +176,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
/* AuthenticationOptions = new List<FileAuthenticationOptions>
|
||||||
{
|
{
|
||||||
new FileAuthenticationOptions
|
new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
@ -173,7 +190,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -184,7 +201,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>{ "api", "api.readOnly", "openid", "offline_access" },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -193,7 +214,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.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(_options, "Test"))
|
||||||
.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))
|
||||||
@ -205,7 +226,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
/* AuthenticationOptions = new List<FileAuthenticationOptions>
|
||||||
{
|
{
|
||||||
new FileAuthenticationOptions
|
new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
@ -219,7 +240,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -230,7 +251,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>{ "api", "openid", "offline_access" },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -239,7 +264,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.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(_options, "Test"))
|
||||||
.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))
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -24,10 +25,20 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private IWebHost _servicebuilder;
|
private IWebHost _servicebuilder;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:52888";
|
||||||
|
|
||||||
public ClaimsToHeadersForwardingTests()
|
public ClaimsToHeadersForwardingTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -47,7 +58,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
/* AuthenticationOptions = new List<FileAuthenticationOptions>
|
||||||
{
|
{
|
||||||
new FileAuthenticationOptions
|
new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
@ -64,7 +75,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -75,7 +86,14 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>
|
||||||
|
{
|
||||||
|
"openid", "offline_access", "api"
|
||||||
|
},
|
||||||
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
@ -91,7 +109,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.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(_options, "Test"))
|
||||||
.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))
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -24,10 +25,20 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private IWebHost _servicebuilder;
|
private IWebHost _servicebuilder;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private string _identityServerRootUrl = "http://localhost:57888";
|
||||||
|
|
||||||
public ClaimsToQueryStringForwardingTests()
|
public ClaimsToQueryStringForwardingTests()
|
||||||
{
|
{
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
|
_options = o =>
|
||||||
|
{
|
||||||
|
o.Authority = _identityServerRootUrl;
|
||||||
|
o.ApiName = "api";
|
||||||
|
o.RequireHttpsMetadata = false;
|
||||||
|
o.SupportedTokens = SupportedTokens.Both;
|
||||||
|
o.ApiSecret = "secret";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -47,7 +58,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
/* AuthenticationOptions = new List<FileAuthenticationOptions>
|
||||||
{
|
{
|
||||||
new FileAuthenticationOptions
|
new FileAuthenticationOptions
|
||||||
{
|
{
|
||||||
@ -64,7 +75,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationProviderKey = "Test"
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -75,7 +86,14 @@ namespace Ocelot.AcceptanceTests
|
|||||||
DownstreamHost = "localhost",
|
DownstreamHost = "localhost",
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>
|
||||||
|
{
|
||||||
|
"openid", "offline_access", "api"
|
||||||
|
},
|
||||||
|
},
|
||||||
AddQueriesToRequest =
|
AddQueriesToRequest =
|
||||||
{
|
{
|
||||||
{"CustomerId", "Claims[CustomerId] > value"},
|
{"CustomerId", "Claims[CustomerId] > value"},
|
||||||
@ -91,7 +109,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.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(_options, "Test"))
|
||||||
.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))
|
||||||
|
@ -3,15 +3,12 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Consul;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Authentication.JsonConverters;
|
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@ -105,9 +102,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var json = reader.ReadToEnd();
|
var json = reader.ReadToEnd();
|
||||||
|
|
||||||
var settings = new JsonSerializerSettings();
|
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
||||||
settings.Converters.Add(new AuthenticationConfigConverter());
|
|
||||||
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
|
|
||||||
|
|
||||||
var response = JsonConvert.SerializeObject(true);
|
var response = JsonConvert.SerializeObject(true);
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
@ -42,11 +42,11 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Shouldly" Version="2.8.3" />
|
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -8,6 +8,8 @@ using System.Net.Http.Headers;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CacheManager.Core;
|
using CacheManager.Core;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -86,6 +88,26 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_ocelotClient = _ocelotServer.CreateClient();
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
||||||
|
/// </summary>
|
||||||
|
public void GivenOcelotIsRunning(Action<IdentityServerAuthenticationOptions> options, string authenticationProviderKey)
|
||||||
|
{
|
||||||
|
_webHostBuilder = new WebHostBuilder();
|
||||||
|
|
||||||
|
_webHostBuilder.ConfigureServices(s =>
|
||||||
|
{
|
||||||
|
s.AddSingleton(_webHostBuilder);
|
||||||
|
s.AddAuthentication()
|
||||||
|
.AddIdentityServerAuthentication(authenticationProviderKey, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
_ocelotServer = new TestServer(_webHostBuilder
|
||||||
|
.UseStartup<Startup>());
|
||||||
|
|
||||||
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
|
}
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingConsulToStoreConfig(ConsulRegistryConfiguration consulConfig)
|
public void GivenOcelotIsRunningUsingConsulToStoreConfig(ConsulRegistryConfiguration consulConfig)
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder();
|
_webHostBuilder = new WebHostBuilder();
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
@ -40,10 +40,10 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.0.1" />
|
<PackageReference Include="IdentityServer4" Version="2.0.2" />
|
||||||
<PackageReference Include="Shouldly" Version="2.8.3" />
|
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3" />
|
<PackageReference Include="Consul" Version="0.7.2.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Moq;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Validator;
|
using Ocelot.Configuration.Validator;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
@ -13,10 +20,12 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private readonly IConfigurationValidator _configurationValidator;
|
private readonly IConfigurationValidator _configurationValidator;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
private Response<ConfigurationValidationResult> _result;
|
private Response<ConfigurationValidationResult> _result;
|
||||||
|
private Mock<IAuthenticationSchemeProvider> _provider;
|
||||||
|
|
||||||
public ConfigurationValidationTests()
|
public ConfigurationValidationTests()
|
||||||
{
|
{
|
||||||
_configurationValidator = new FileConfigurationValidator();
|
_provider = new Mock<IAuthenticationSchemeProvider>();
|
||||||
|
_configurationValidator = new FileConfigurationValidator(_provider.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -62,50 +71,48 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
this.Given(x => x.GivenAConfiguration(new FileConfiguration
|
this.Given(x => x.GivenAConfiguration(new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/api/products/",
|
DownstreamPathTemplate = "/api/products/",
|
||||||
UpstreamPathTemplate = "http://asdf.com",
|
UpstreamPathTemplate = "http://asdf.com",
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions()
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
.And(x => x.GivenTheAuthSchemeExists("Test"))
|
||||||
.When(x => x.WhenIValidateTheConfiguration())
|
.When(x => x.WhenIValidateTheConfiguration())
|
||||||
.Then(x => x.ThenTheResultIsValid())
|
.Then(x => x.ThenTheResultIsValid())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GivenTheAuthSchemeExists(string name)
|
||||||
|
{
|
||||||
|
_provider.Setup(x => x.GetAllSchemesAsync()).ReturnsAsync(new List<AuthenticationScheme>
|
||||||
|
{
|
||||||
|
new AuthenticationScheme(name, name, typeof(TestHandler))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void configuration_is_invalid_with_invalid_authentication_provider()
|
public void configuration_is_invalid_with_invalid_authentication_provider()
|
||||||
{
|
{
|
||||||
this.Given(x => x.GivenAConfiguration(new FileConfiguration
|
this.Given(x => x.GivenAConfiguration(new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
Provider = "BootyBootyBottyRockinEverywhere",
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
{
|
{
|
||||||
DownstreamPathTemplate = "/api/products/",
|
DownstreamPathTemplate = "/api/products/",
|
||||||
UpstreamPathTemplate = "http://asdf.com",
|
UpstreamPathTemplate = "http://asdf.com",
|
||||||
AuthenticationProviderKey = "Test"
|
AuthenticationOptions = new FileAuthenticationOptions()
|
||||||
}
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
} }
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.When(x => x.WhenIValidateTheConfiguration())
|
.When(x => x.WhenIValidateTheConfiguration())
|
||||||
@ -146,7 +153,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void WhenIValidateTheConfiguration()
|
private void WhenIValidateTheConfiguration()
|
||||||
{
|
{
|
||||||
_result = _configurationValidator.IsValid(_fileConfiguration);
|
_result = _configurationValidator.IsValid(_fileConfiguration).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheResultIsValid()
|
private void ThenTheResultIsValid()
|
||||||
@ -163,5 +170,23 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_result.Data.Errors[0].ShouldBeOfType<T>();
|
_result.Data.Errors[0].ShouldBeOfType<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestOptions : AuthenticationSchemeOptions
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestHandler : AuthenticationHandler<TestOptions>
|
||||||
|
{
|
||||||
|
public TestHandler(IOptionsMonitor<TestOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
|
{
|
||||||
|
var principal = new ClaimsPrincipal();
|
||||||
|
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -446,16 +446,14 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
||||||
public void should_create_with_headers_to_extract(string provider, IAuthenticationConfig config, FileConfiguration fileConfig)
|
public void should_create_with_headers_to_extract(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(provider)
|
|
||||||
.WithAllowedScopes(new List<string>())
|
.WithAllowedScopes(new List<string>())
|
||||||
.WithConfig(config)
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var expected = new List<ReRoute>
|
var expected = new List<ReRoute>
|
||||||
@ -480,23 +478,21 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.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(provider, expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
||||||
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
[MemberData(nameof(AuthenticationConfigTestData.GetAuthenticationData), MemberType = typeof(AuthenticationConfigTestData))]
|
||||||
public void should_create_with_authentication_properties(string provider, IAuthenticationConfig config, FileConfiguration fileConfig)
|
public void should_create_with_authentication_properties(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(provider)
|
|
||||||
.WithAllowedScopes(new List<string>())
|
.WithAllowedScopes(new List<string>())
|
||||||
.WithConfig(config)
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var expected = new List<ReRoute>
|
var expected = new List<ReRoute>
|
||||||
@ -516,7 +512,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.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(provider, expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
||||||
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
@ -538,7 +534,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_validator
|
_validator
|
||||||
.Setup(x => x.IsValid(It.IsAny<FileConfiguration>()))
|
.Setup(x => x.IsValid(It.IsAny<FileConfiguration>()))
|
||||||
.Returns(new OkResponse<ConfigurationValidationResult>(new ConfigurationValidationResult(false)));
|
.ReturnsAsync(new OkResponse<ConfigurationValidationResult>(new ConfigurationValidationResult(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheConfigIs(FileConfiguration fileConfiguration)
|
private void GivenTheConfigIs(FileConfiguration fileConfiguration)
|
||||||
@ -587,34 +583,13 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheAuthenticationOptionsAre(string provider, List<ReRoute> expectedReRoutes)
|
private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||||
{
|
{
|
||||||
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
|
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
|
||||||
var expected = expectedReRoutes[i].AuthenticationOptions;
|
var expected = expectedReRoutes[i].AuthenticationOptions;
|
||||||
|
|
||||||
result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||||
result.Provider.ShouldBe(expected.Provider);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,14 +641,14 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private void GivenTheAuthOptionsCreatorReturns(AuthenticationOptions authOptions)
|
private void GivenTheAuthOptionsCreatorReturns(AuthenticationOptions authOptions)
|
||||||
{
|
{
|
||||||
_authOptionsCreator
|
_authOptionsCreator
|
||||||
.Setup(x => x.Create(It.IsAny<FileReRoute>(), It.IsAny<List<FileAuthenticationOptions>>()))
|
.Setup(x => x.Create(It.IsAny<FileReRoute>()))
|
||||||
.Returns(authOptions);
|
.Returns(authOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheAuthOptionsCreatorIsCalledCorrectly()
|
private void ThenTheAuthOptionsCreatorIsCalledCorrectly()
|
||||||
{
|
{
|
||||||
_authOptionsCreator
|
_authOptionsCreator
|
||||||
.Verify(x => x.Create(_fileConfiguration.ReRoutes[0], _fileConfiguration.AuthenticationOptions), Times.Once);
|
.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheUpstreamTemplatePatternCreatorReturns(string pattern)
|
private void GivenTheUpstreamTemplatePatternCreatorReturns(string pattern)
|
||||||
|
@ -34,7 +34,10 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
ExceptionsAllowedBeforeBreaking = 1,
|
ExceptionsAllowedBeforeBreaking = 1,
|
||||||
TimeoutValue = 1
|
TimeoutValue = 1
|
||||||
},
|
},
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationOptions = new FileAuthenticationOptions()
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test"
|
||||||
|
},
|
||||||
RouteClaimsRequirement = new Dictionary<string, string>()
|
RouteClaimsRequirement = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{"",""}
|
{"",""}
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Net;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.TestHost;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Shouldly;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests
|
|
||||||
{
|
|
||||||
public class DynamicSchemeTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public async Task OptionsAreConfiguredOnce()
|
|
||||||
{
|
|
||||||
var server = CreateServer(s =>
|
|
||||||
{
|
|
||||||
s.Configure<TestOptions>("One", o => o.Instance = new Singleton());
|
|
||||||
});
|
|
||||||
// Add One scheme
|
|
||||||
var response = await server.CreateClient().GetAsync("http://example.com/add/One");
|
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
||||||
var transaction = await server.CreateClient().GetAsync("http://example.com/auth/One");
|
|
||||||
var result = await transaction.Content.ReadAsStringAsync();
|
|
||||||
result.ShouldBe("True");
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestOptions : AuthenticationSchemeOptions
|
|
||||||
{
|
|
||||||
public Singleton Instance { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Singleton
|
|
||||||
{
|
|
||||||
public static int _count;
|
|
||||||
|
|
||||||
public Singleton()
|
|
||||||
{
|
|
||||||
_count++;
|
|
||||||
Count = _count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestHandler : AuthenticationHandler<TestOptions>
|
|
||||||
{
|
|
||||||
public TestHandler(IOptionsMonitor<TestOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
|
||||||
{
|
|
||||||
var principal = new ClaimsPrincipal();
|
|
||||||
var id = new ClaimsIdentity("Ocelot");
|
|
||||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, Scheme.Name, ClaimValueTypes.String, Scheme.Name));
|
|
||||||
if (Options.Instance != null)
|
|
||||||
{
|
|
||||||
id.AddClaim(new Claim("Count", Options.Instance.Count.ToString()));
|
|
||||||
}
|
|
||||||
principal.AddIdentity(id);
|
|
||||||
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TestServer CreateServer(Action<IServiceCollection> configureServices = null)
|
|
||||||
{
|
|
||||||
var builder = new WebHostBuilder()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseAuthentication();
|
|
||||||
app.Use(async (context, next) =>
|
|
||||||
{
|
|
||||||
var req = context.Request;
|
|
||||||
var res = context.Response;
|
|
||||||
if (req.Path.StartsWithSegments(new PathString("/add"), out var remainder))
|
|
||||||
{
|
|
||||||
var name = remainder.Value.Substring(1);
|
|
||||||
var auth = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
|
|
||||||
var scheme = new AuthenticationScheme(name, name, typeof(TestHandler));
|
|
||||||
auth.AddScheme(scheme);
|
|
||||||
}
|
|
||||||
else if (req.Path.StartsWithSegments(new PathString("/auth"), out remainder))
|
|
||||||
{
|
|
||||||
var name = (remainder.Value.Length > 0) ? remainder.Value.Substring(1) : null;
|
|
||||||
var result = await context.AuthenticateAsync(name);
|
|
||||||
context.User = result.Principal;
|
|
||||||
await res.WriteJsonAsync(context.User.Identity.IsAuthenticated.ToString());
|
|
||||||
}
|
|
||||||
else if (req.Path.StartsWithSegments(new PathString("/remove"), out remainder))
|
|
||||||
{
|
|
||||||
var name = remainder.Value.Substring(1);
|
|
||||||
var auth = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
|
|
||||||
auth.RemoveScheme(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.ConfigureServices(services =>
|
|
||||||
{
|
|
||||||
configureServices?.Invoke(services);
|
|
||||||
services.AddAuthentication();
|
|
||||||
});
|
|
||||||
return new TestServer(builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -34,9 +34,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||||
@ -44,10 +44,10 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.7.99" />
|
<PackageReference Include="Moq" Version="4.7.142" />
|
||||||
<PackageReference Include="Shouldly" Version="2.8.3" />
|
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Responder
|
|||||||
[InlineData(OcelotErrorCode.RequestTimedOutError)]
|
[InlineData(OcelotErrorCode.RequestTimedOutError)]
|
||||||
public void should_return_service_unavailable(OcelotErrorCode errorCode)
|
public void should_return_service_unavailable(OcelotErrorCode errorCode)
|
||||||
{
|
{
|
||||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.ServiceUnavailable);
|
ShouldMapErrorToStatusCode(OcelotErrorCode.RequestTimedOutError, HttpStatusCode.ServiceUnavailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
namespace Ocelot.UnitTests.TestData
|
namespace Ocelot.UnitTests.TestData
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
public class AuthenticationConfigTestData
|
public class AuthenticationConfigTestData
|
||||||
@ -11,31 +9,8 @@
|
|||||||
{
|
{
|
||||||
yield return new object[]
|
yield return new object[]
|
||||||
{
|
{
|
||||||
"IdentityServer",
|
|
||||||
new IdentityServerConfigBuilder()
|
|
||||||
.WithRequireHttps(true)
|
|
||||||
.WithApiName("test")
|
|
||||||
.WithApiSecret("test")
|
|
||||||
.WithProviderRootUrl("test")
|
|
||||||
.Build(),
|
|
||||||
new FileConfiguration
|
new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
IdentityServerConfig = new FileIdentityServerConfig
|
|
||||||
{
|
|
||||||
ProviderRootUrl = "http://localhost:51888",
|
|
||||||
RequireHttps = false,
|
|
||||||
ApiName = "api",
|
|
||||||
ApiSecret = "secret"
|
|
||||||
} ,
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -44,11 +19,15 @@
|
|||||||
DownstreamPathTemplate = "/products/{productId}",
|
DownstreamPathTemplate = "/products/{productId}",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
ReRouteIsCaseSensitive = true,
|
ReRouteIsCaseSensitive = true,
|
||||||
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>(),
|
||||||
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
{ "CustomerId", "Claims[CustomerId] > value" },
|
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,27 +35,8 @@
|
|||||||
|
|
||||||
yield return new object[]
|
yield return new object[]
|
||||||
{
|
{
|
||||||
"Jwt",
|
|
||||||
new JwtConfigBuilder()
|
|
||||||
.WithAudience("a")
|
|
||||||
.WithAuthority("au")
|
|
||||||
.Build(),
|
|
||||||
new FileConfiguration
|
new FileConfiguration
|
||||||
{
|
{
|
||||||
AuthenticationOptions = new List<FileAuthenticationOptions>
|
|
||||||
{
|
|
||||||
new FileAuthenticationOptions
|
|
||||||
{
|
|
||||||
AllowedScopes = new List<string>(),
|
|
||||||
Provider = "IdentityServer",
|
|
||||||
JwtConfig = new FileJwtConfig
|
|
||||||
{
|
|
||||||
Audience = "a",
|
|
||||||
Authority = "au"
|
|
||||||
},
|
|
||||||
AuthenticationProviderKey = "Test"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
{
|
{
|
||||||
new FileReRoute
|
new FileReRoute
|
||||||
@ -85,7 +45,11 @@
|
|||||||
DownstreamPathTemplate = "/products/{productId}",
|
DownstreamPathTemplate = "/products/{productId}",
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
ReRouteIsCaseSensitive = true,
|
ReRouteIsCaseSensitive = true,
|
||||||
AuthenticationProviderKey = "Test",
|
AuthenticationOptions = new FileAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationProviderKey = "Test",
|
||||||
|
AllowedScopes = new List<string>(),
|
||||||
|
},
|
||||||
AddHeadersToRequest =
|
AddHeadersToRequest =
|
||||||
{
|
{
|
||||||
{ "CustomerId", "Claims[CustomerId] > value" },
|
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user