miles away

This commit is contained in:
Tom Pallister 2017-09-26 09:57:51 +01:00
parent 6419919e74
commit d8621d9046
6 changed files with 159 additions and 78 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using IdentityServer4.AccessTokenValidation; using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -21,22 +22,22 @@ namespace Ocelot.Authentication.Handler.Creator
throw new NotImplementedException(); throw new NotImplementedException();
var builder = app.New(); var builder = app.New();
if (authOptions.Provider.ToLower() == "jwt") /* if (authOptions.Provider.ToLower() == "jwt")
{ {
var authenticationConfig = authOptions.Config as JwtConfig; var authenticationConfig = authOptions.Config as JwtConfig;
/* builder.UseJwtBearerAuthentication( builder.UseJwtBearerAuthentication(
new JwtBearerOptions() new JwtBearerOptions()
{ {
Authority = authenticationConfig.Authority, Authority = authenticationConfig.Authority,
Audience = authenticationConfig.Audience Audience = authenticationConfig.Audience
});*/ });
} }
else else
{ {
var authenticationConfig = authOptions.Config as IdentityServerConfig; var authenticationConfig = authOptions.Config as IdentityServerConfig;
/* builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{ {
Authority = authenticationConfig.ProviderRootUrl, Authority = authenticationConfig.ProviderRootUrl,
ApiName = authenticationConfig.ApiName, ApiName = authenticationConfig.ApiName,
@ -44,11 +45,12 @@ namespace Ocelot.Authentication.Handler.Creator
AllowedScopes = authOptions.AllowedScopes, AllowedScopes = authOptions.AllowedScopes,
SupportedTokens = SupportedTokens.Both, SupportedTokens = SupportedTokens.Both,
ApiSecret = authenticationConfig.ApiSecret ApiSecret = authenticationConfig.ApiSecret
});*/ });
} }*/
var authenticationNext = builder.Build(); var authenticationNext = builder.Build();
return new OkResponse<RequestDelegate>(authenticationNext); return new OkResponse<RequestDelegate>(authenticationNext);
} }
} }

View File

@ -1,7 +1,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks; using System.Threading.Tasks;
using IdentityServer4.Extensions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ocelot.Authentication.Handler.Factory; using Ocelot.Authentication.Handler.Factory;
using Ocelot.Configuration; using Ocelot.Configuration;
using Ocelot.Errors; using Ocelot.Errors;
@ -34,6 +41,32 @@ namespace Ocelot.Authentication.Middleware
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
{ {
/* 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);
result.Principal.IsAuthenticated();
}
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.Invoke(context);
}*/
if (IsAuthenticatedRoute(DownstreamRoute.ReRoute)) if (IsAuthenticatedRoute(DownstreamRoute.ReRoute))
{ {
_logger.LogDebug($"{context.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated"); _logger.LogDebug($"{context.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated");
@ -81,5 +114,43 @@ namespace Ocelot.Authentication.Middleware
return reRoute.IsAuthenticated; return reRoute.IsAuthenticated;
} }
} }
public 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();
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)));
}
}
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; }
}
} }

View File

@ -38,10 +38,14 @@ using Ocelot.Responder;
using Ocelot.ServiceDiscovery; using Ocelot.ServiceDiscovery;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Ocelot.Configuration; using Ocelot.Configuration;
using Ocelot.Creator.Configuration; using Ocelot.Creator.Configuration;
@ -75,7 +79,6 @@ namespace Ocelot.DependencyInjection
services.TryAddSingleton<IAuthenticationProviderConfigCreator, AuthenticationProviderConfigCreator>(); services.TryAddSingleton<IAuthenticationProviderConfigCreator, AuthenticationProviderConfigCreator>();
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>(); services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
services.TryAddSingleton<IConfigurationValidator, FileConfigurationValidator>(); services.TryAddSingleton<IConfigurationValidator, FileConfigurationValidator>();
services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>(); services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>(); services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
services.TryAddSingleton<IUpstreamTemplatePatternCreator, UpstreamTemplatePatternCreator>(); services.TryAddSingleton<IUpstreamTemplatePatternCreator, UpstreamTemplatePatternCreator>();
@ -84,59 +87,7 @@ namespace Ocelot.DependencyInjection
services.TryAddSingleton<IQoSOptionsCreator, QoSOptionsCreator>(); services.TryAddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
services.TryAddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>(); services.TryAddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>(); services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration();
if(identityServerConfiguration != null)
{
services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
services.TryAddSingleton<IHashMatcher, HashMatcher>();
var identityServerBuilder = services
.AddIdentityServer(options => {
options.IssuerUri = "Ocelot";
})
.AddInMemoryApiResources(new List<ApiResource>
{
new ApiResource
{
Name = identityServerConfiguration.ApiName,
Description = identityServerConfiguration.Description,
Enabled = identityServerConfiguration.Enabled,
DisplayName = identityServerConfiguration.ApiName,
Scopes = identityServerConfiguration.AllowedScopes.Select(x => new Scope(x)).ToList(),
ApiSecrets = new List<Secret>
{
new Secret
{
Value = identityServerConfiguration.ApiSecret.Sha256()
}
}
}
})
.AddInMemoryClients(new List<Client>
{
new Client
{
ClientId = identityServerConfiguration.ApiName,
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = new List<Secret> {new Secret(identityServerConfiguration.ApiSecret.Sha256())},
AllowedScopes = identityServerConfiguration.AllowedScopes,
AccessTokenType = identityServerConfiguration.AccessTokenType,
Enabled = identityServerConfiguration.Enabled,
RequireClientSecret = identityServerConfiguration.RequireClientSecret
}
}).AddResourceOwnerValidator<OcelotResourceOwnerPasswordValidator>();
if (string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificateLocation) || string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificatePassword))
{
identityServerBuilder.AddDeveloperSigningCredential();
}
else
{
var cert = new X509Certificate2(identityServerConfiguration.CredentialsSigningCertificateLocation, identityServerConfiguration.CredentialsSigningCertificatePassword);
identityServerBuilder.AddSigningCredential(cert);
}
}
var assembly = typeof(FileConfigurationController).GetTypeInfo().Assembly; var assembly = typeof(FileConfigurationController).GetTypeInfo().Assembly;
@ -190,6 +141,76 @@ namespace Ocelot.DependencyInjection
//Used to log the the start and ending of middleware //Used to log the the start and ending of middleware
services.TryAddSingleton<OcelotDiagnosticListener>(); services.TryAddSingleton<OcelotDiagnosticListener>();
services.AddMiddlewareAnalysis(); services.AddMiddlewareAnalysis();
services.AddWebEncoders();
var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration();
if (identityServerConfiguration != null)
{
services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
services.TryAddSingleton<IHashMatcher, HashMatcher>();
var identityServerBuilder = services
.AddIdentityServer(options => {
options.IssuerUri = "Ocelot";
})
.AddInMemoryApiResources(new List<ApiResource>
{
new ApiResource
{
Name = identityServerConfiguration.ApiName,
Description = identityServerConfiguration.Description,
Enabled = identityServerConfiguration.Enabled,
DisplayName = identityServerConfiguration.ApiName,
Scopes = identityServerConfiguration.AllowedScopes.Select(x => new Scope(x)).ToList(),
ApiSecrets = new List<Secret>
{
new Secret
{
Value = identityServerConfiguration.ApiSecret.Sha256()
}
}
}
})
.AddInMemoryClients(new List<Client>
{
new Client
{
ClientId = identityServerConfiguration.ApiName,
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = new List<Secret> {new Secret(identityServerConfiguration.ApiSecret.Sha256())},
AllowedScopes = identityServerConfiguration.AllowedScopes,
AccessTokenType = identityServerConfiguration.AccessTokenType,
Enabled = identityServerConfiguration.Enabled,
RequireClientSecret = identityServerConfiguration.RequireClientSecret
}
}).AddResourceOwnerValidator<OcelotResourceOwnerPasswordValidator>();
var whb = services.First(x => x.ServiceType == typeof(IWebHostBuilder));
var urlFinder = new BaseUrlFinder((IWebHostBuilder)whb.ImplementationInstance);
var baseSchemeUrlAndPort = urlFinder.Find();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(o =>
{
o.Authority = baseSchemeUrlAndPort + "admin";
o.ApiName = identityServerConfiguration.ApiName;
o.RequireHttpsMetadata = identityServerConfiguration.RequireHttps;
o.AllowedScopes = identityServerConfiguration.AllowedScopes;
o.SupportedTokens = SupportedTokens.Both;
o.ApiSecret = identityServerConfiguration.ApiSecret;
});
if (string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificateLocation) || string.IsNullOrEmpty(identityServerConfiguration.CredentialsSigningCertificatePassword))
{
identityServerBuilder.AddDeveloperSigningCredential();
}
else
{
var cert = new X509Certificate2(identityServerConfiguration.CredentialsSigningCertificateLocation, identityServerConfiguration.CredentialsSigningCertificatePassword);
identityServerBuilder.AddSigningCredential(cert);
}
}
return services; return services;
} }

View File

@ -1,11 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using IdentityServer4.AccessTokenValidation; using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Ocelot.Authentication.Middleware; using Ocelot.Authentication.Middleware;
using Ocelot.Cache.Middleware; using Ocelot.Cache.Middleware;
using Ocelot.Claims.Middleware; using Ocelot.Claims.Middleware;
using Ocelot.Controllers;
using Ocelot.DownstreamRouteFinder.Middleware; using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamUrlCreator.Middleware; using Ocelot.DownstreamUrlCreator.Middleware;
using Ocelot.Errors.Middleware; using Ocelot.Errors.Middleware;
@ -179,28 +181,12 @@ namespace Ocelot.Middleware
if(!string.IsNullOrEmpty(configuration.AdministrationPath) && identityServerConfiguration != null) if(!string.IsNullOrEmpty(configuration.AdministrationPath) && identityServerConfiguration != null)
{ {
var urlFinder = (IBaseUrlFinder)builder.ApplicationServices.GetService(typeof(IBaseUrlFinder));
var baseSchemeUrlAndPort = urlFinder.Find();
builder.Map(configuration.AdministrationPath, app => builder.Map(configuration.AdministrationPath, app =>
{ {
var identityServerUrl = $"{baseSchemeUrlAndPort}/{configuration.AdministrationPath.Remove(0,1)}"; app.UseMvc();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(o =>
{
o.Authority = identityServerUrl;
o.ApiName = identityServerConfiguration.ApiName;
o.RequireHttpsMetadata = identityServerConfiguration.RequireHttps;
o.AllowedScopes = identityServerConfiguration.AllowedScopes;
o.SupportedTokens = SupportedTokens.Both;
o.ApiSecret = identityServerConfiguration.ApiSecret;
});
app.UseIdentityServer(); app.UseIdentityServer();
app.UseAuthentication(); app.UseAuthentication();
app.UseMvc();
}); });
} }
} }

View File

@ -26,6 +26,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.0.0-rc1" />
<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" />
@ -36,7 +37,6 @@
<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="System.Text.RegularExpressions" Version="4.3.0" /> <PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.0.0-rc1" />
<PackageReference Include="CacheManager.Core" Version="1.1.1" /> <PackageReference Include="CacheManager.Core" Version="1.1.1" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.1" /> <PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.1" />
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.1" /> <PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.1" />

View File

@ -0,0 +1 @@
{"KeyId":"6aad821b3e366a0189ea6c9741eae6ba","Parameters":{"D":"RcfIF/iJ8qnKpHlaJCa9Qz+iN9Z655mfW0B/CycZx0WDQwQtjYNF+ijEkqfpGC3TJ9n19vXHdDEGfONxHwTtgS6PP/VIYYmql7OfCn+tkZUvMeIXykfEXFoNoWJXlT3eMI1JWyZpT/dZJLtmdeY09csDU/LjXTlyFrljW361T0NR/azAHqEfeuoKhqaJ2klzTzjif4xO5kMcTBHVyxrZm0+cbowsKPjI1QRh5xXsst8EDrM7rXStz4enneNaNbvP1nmWx++F7zn+5/WBDcPJVnL1HiyAzMAHj+oXG2JwDizO4RJxLbvQa2Y2jzoDp/qc++s2HWFo1PmuUnOzNIQjyQ==","DP":"x3VwsILF1yo8puLB6TOcb4hMWngz8rqjBl3dty4E3Un7UexVh+NkqTiSXWZNern6Ka6gE8CpdDXhQiYCFbcnBiSF6FVSpjpQ+Qf9PeRj5HipJF+DzGyEOTzwOiBjb6s5CvPUQWvJiqQoP1D+1V+X/+C0zug8+Df73UyHA7uieKc=","DQ":"aaZu9GfgKqUiy0uwPkmnLcwIEDqRlLG14c23OOoEqNRHK9T3OwUKEJ1qK0mbMKIVTwklyiC7uZHqMijIqk0LovTL4nI3LRlDkRjhUsIuubZZOAw7sYYemBUl+wEB/VZofaJ7H/CYtCUXyJhND2DFbTjzgeg3uWoMpyMDHuH/9Pc=","Exponent":"AQAB","InverseQ":"YRV4QA6rwB9BEHjzh5Wk3TcSS1CrwJWVopj/qC1amXxhtM3aMb4ZfKk7XoynLqHyQ86rB2p7dPNP2GL+fIWbt4h/ESO9JqOlM/bVXpdyCvIwchAL82hfHb4FRv+V+J2cksaIA+bHt7ye9n/XSmSr8v0WsjxN2qHzdla3t+J0c1I=","Modulus":"xLJZzQyYbJAqymvvJeig9H4cfXEy3t0KVnRuUumdSBzU/3F7q1vCDBkXLqs8icEv9ZL4MUgDzzSjjYJpVXzvC24L1My3NLhSSZOCGrhSHCx98+cAgrb71tirXXsiBMXKeGhnJ05KopHtPRJVxBvd3d3Kee957y86g1Sbho1XxwWsrzVu5E7YZS+NkJycHkiUseMKeQ+tMLbPoFZPu5EqrrsSWuDjb7XNUjJViyGaOtvL2SQ9QtvDu006fe4m0VVw71ycSt2ReAmlA+EgCFsyLYBIoAhlk7k+lKyYO3a/8E0bzltB6MGaRaGJMB0C9pSxAfGSmSpIi2OUy0YIpIoDoQ==","P":"ydx6DVoXf3DgS6WZtrR82xNf12kLD5cGUToPwwIjjX5oQywOhGXOV4GCrqISDff2bosrPvleBfuJ5KH9KRVAaEjh1At554Bq+Nw8cc/1mTXEOSKENDtA9GjkpthR0QW1FDFRR5Tc8sRuoBpulN1rJIDIkfEkqwlpugFmk2UrDk8=","Q":"+XNIV8qMorQ11C1fVj4L91wufF4NqVqCdm/PN3f+xZ5UWoiCOil+njRuIL09ZifEwy3fgqD06Fu/SvaqMODyKAzA+RMUJU0sk92aOzAhKiGBk38sEvEuDUKZYNJm5NLjo9XXBG8DQzSUPvmIFLaMCloA95Ozie0mJcrXcimCww8="}}