mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 09:38:14 +08:00
got identity server access token acceptance test working, created factory for choosing auth handlers, a creator for making the auth handlers, some general refactoring...next step is injecting the config for the auth handler creator in some way or just passing it in
This commit is contained in:
@ -0,0 +1,16 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Authentication
|
||||
{
|
||||
public class AuthenticationHandler
|
||||
{
|
||||
public AuthenticationHandler(string provider, RequestDelegate handler)
|
||||
{
|
||||
Provider = provider;
|
||||
Handler = handler;
|
||||
}
|
||||
|
||||
public string Provider { get; private set; }
|
||||
public RequestDelegate Handler { get; private set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Library.Infrastructure.Responses;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Cannot unit test things in this class due to use of extension methods
|
||||
/// </summary>
|
||||
public class AuthenticationHandlerCreator : IAuthenticationHandlerCreator
|
||||
{
|
||||
public Response<RequestDelegate> CreateIdentityServerAuthenticationHandler(IApplicationBuilder app)
|
||||
{
|
||||
var builder = app.New();
|
||||
|
||||
builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
||||
{
|
||||
//todo sort these options out
|
||||
Authority = "http://localhost:51888",
|
||||
ScopeName = "api",
|
||||
|
||||
RequireHttpsMetadata = false
|
||||
});
|
||||
|
||||
builder.UseMvc();
|
||||
|
||||
var authenticationNext = builder.Build();
|
||||
|
||||
return new OkResponse<RequestDelegate>(authenticationNext);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Ocelot.Library.Infrastructure.Errors;
|
||||
using Ocelot.Library.Infrastructure.Responses;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Authentication
|
||||
{
|
||||
public class AuthenticationProviderFactory : IAuthenticationProviderFactory
|
||||
{
|
||||
private readonly IAuthenticationHandlerCreator _creator;
|
||||
|
||||
public AuthenticationProviderFactory(IAuthenticationHandlerCreator creator)
|
||||
{
|
||||
_creator = creator;
|
||||
}
|
||||
|
||||
public Response<AuthenticationHandler> Get(string provider, IApplicationBuilder app)
|
||||
{
|
||||
var handler = _creator.CreateIdentityServerAuthenticationHandler(app);
|
||||
|
||||
if (!handler.IsError)
|
||||
{
|
||||
return new OkResponse<AuthenticationHandler>(new AuthenticationHandler(provider, handler.Data));
|
||||
}
|
||||
|
||||
return new ErrorResponse<AuthenticationHandler>(new List<Error>
|
||||
{
|
||||
new UnableToCreateAuthenticationHandlerError($"Unable to create authentication handler for {provider}")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Library.Infrastructure.Responses;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Authentication
|
||||
{
|
||||
public interface IAuthenticationHandlerCreator
|
||||
{
|
||||
Response<RequestDelegate> CreateIdentityServerAuthenticationHandler(IApplicationBuilder app);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Ocelot.Library.Infrastructure.Responses;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Authentication
|
||||
{
|
||||
public interface IAuthenticationProviderFactory
|
||||
{
|
||||
Response<AuthenticationHandler> Get(string provider, IApplicationBuilder app);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using Ocelot.Library.Infrastructure.Errors;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Authentication
|
||||
{
|
||||
public class UnableToCreateAuthenticationHandlerError : Error
|
||||
{
|
||||
public UnableToCreateAuthenticationHandlerError(string message)
|
||||
: base(message, OcelotErrorCode.UnableToCreateAuthenticationHandlerError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
UnableToFindDownstreamRouteError,
|
||||
CannotAddDataError,
|
||||
CannotFindDataError,
|
||||
UnableToCompleteRequestError
|
||||
UnableToCompleteRequestError,
|
||||
UnableToCreateAuthenticationHandlerError
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -7,6 +8,11 @@ using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
|
||||
using Ocelot.Library.Infrastructure.Errors;
|
||||
using Ocelot.Library.Infrastructure.Repository;
|
||||
using Ocelot.Library.Infrastructure.Responses;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Library.Infrastructure.Authentication;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Middleware
|
||||
{
|
||||
@ -16,13 +22,15 @@ namespace Ocelot.Library.Infrastructure.Middleware
|
||||
private RequestDelegate _authenticationNext;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
private readonly IApplicationBuilder _app;
|
||||
private readonly IAuthenticationProviderFactory _authProviderFactory;
|
||||
|
||||
public AuthenticationMiddleware(RequestDelegate next, IApplicationBuilder app,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
IScopedRequestDataRepository scopedRequestDataRepository, IAuthenticationProviderFactory authProviderFactory)
|
||||
: base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
_authProviderFactory = authProviderFactory;
|
||||
_app = app;
|
||||
}
|
||||
|
||||
@ -38,25 +46,17 @@ namespace Ocelot.Library.Infrastructure.Middleware
|
||||
|
||||
if (IsAuthenticatedRoute(downstreamRoute.Data.ReRoute))
|
||||
{
|
||||
//todo - build auth pipeline and then call normal pipeline if all good?
|
||||
//create new app builder
|
||||
var builder = _app.New();
|
||||
//set up any options for the authentication
|
||||
var jwtBearerOptions = new JwtBearerOptions
|
||||
var authenticationNext = _authProviderFactory.Get(downstreamRoute.Data.ReRoute.AuthenticationProvider, _app);
|
||||
|
||||
if (!authenticationNext.IsError)
|
||||
{
|
||||
AutomaticAuthenticate = true,
|
||||
AutomaticChallenge = true,
|
||||
RequireHttpsMetadata = false,
|
||||
};
|
||||
//set the authentication middleware
|
||||
builder.UseJwtBearerAuthentication(jwtBearerOptions);
|
||||
//use mvc so we hit the catch all authorised controller
|
||||
builder.UseMvc();
|
||||
//then build it
|
||||
_authenticationNext = builder.Build();
|
||||
//then call it
|
||||
await _authenticationNext(context);
|
||||
//check if the user is authenticated
|
||||
await authenticationNext.Data.Handler.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPipelineError(authenticationNext.Errors);
|
||||
}
|
||||
|
||||
if (context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
|
@ -43,7 +43,6 @@ namespace Ocelot.Library.Infrastructure.Middleware
|
||||
{
|
||||
await _responder.CreateErrorResponse(context, 500);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3,7 +3,11 @@ using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ocelot.Library.Infrastructure.Responder
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Cannot unit test things in this class due to methods not being implemented
|
||||
/// on .net concretes used for testing
|
||||
/// </summary>
|
||||
public class HttpContextResponder : IHttpResponder
|
||||
{
|
||||
public async Task<HttpContext> CreateResponse(HttpContext context, HttpResponseMessage response)
|
||||
|
@ -1,34 +1,35 @@
|
||||
{
|
||||
"version": "1.0.0-*",
|
||||
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"version": "1.0.0",
|
||||
"type": "platform"
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"version": "1.0.0",
|
||||
"type": "platform"
|
||||
},
|
||||
"Microsoft.AspNetCore.Mvc": "1.0.0",
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
|
||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
||||
"Microsoft.Extensions.Logging": "1.0.0",
|
||||
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
||||
"Microsoft.Extensions.Logging.Debug": "1.0.0",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
||||
"Microsoft.AspNetCore.Http": "1.0.0",
|
||||
"System.Text.RegularExpressions": "4.1.0",
|
||||
"YamlDotNet": "3.9.0",
|
||||
"Microsoft.AspNetCore.Authentication.OAuth": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Google": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Facebook": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Twitter": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.MicrosoftAccount": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication": "1.0.0",
|
||||
"IdentityServer4.AccessTokenValidation": "1.0.1-rc2"
|
||||
},
|
||||
"Microsoft.AspNetCore.Mvc": "1.0.0",
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
|
||||
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
||||
"Microsoft.Extensions.Logging": "1.0.0",
|
||||
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
||||
"Microsoft.Extensions.Logging.Debug": "1.0.0",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
||||
"Microsoft.AspNetCore.Http": "1.0.0",
|
||||
"System.Text.RegularExpressions": "4.1.0",
|
||||
"YamlDotNet": "3.9.0",
|
||||
"Microsoft.AspNetCore.Authentication.OAuth": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Google": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Facebook": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.Twitter": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication.MicrosoftAccount": "1.0.0",
|
||||
"Microsoft.AspNetCore.Authentication": "1.0.0"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"netcoreapp1.4": {
|
||||
|
@ -7,6 +7,7 @@ using Microsoft.Extensions.Configuration.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Ocelot.Library.Infrastructure.Authentication;
|
||||
using Ocelot.Library.Infrastructure.Configuration;
|
||||
using Ocelot.Library.Infrastructure.Configuration.Yaml;
|
||||
using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
|
||||
@ -41,7 +42,8 @@ namespace Ocelot
|
||||
{
|
||||
services.AddOptions();
|
||||
services.AddMvc();
|
||||
|
||||
services.AddMvcCore().AddAuthorization().AddJsonFormatters();
|
||||
|
||||
services.Configure<YamlConfiguration>(Configuration);
|
||||
services.AddAuthentication();
|
||||
|
||||
@ -55,6 +57,8 @@ namespace Ocelot
|
||||
services.AddSingleton<IHttpResponder, HttpContextResponder>();
|
||||
services.AddSingleton<IRequestBuilder, HttpRequestBuilder>();
|
||||
services.AddSingleton<IErrorsToHttpStatusCodeMapper, ErrorsToHttpStatusCodeMapper>();
|
||||
services.AddSingleton<IAuthenticationProviderFactory, AuthenticationProviderFactory>();
|
||||
services.AddSingleton<IAuthenticationHandlerCreator, AuthenticationHandlerCreator>();
|
||||
|
||||
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
Reference in New Issue
Block a user