mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-07-07 19:27:15 +08:00
Added a get authentication test, removed the infrastructure name space as it seemed pointless, started thinking about how to pass claims on with the request
This commit is contained in:
73
src/Ocelot.Library/Middleware/AuthenticationMiddleware.cs
Normal file
73
src/Ocelot.Library/Middleware/AuthenticationMiddleware.cs
Normal file
@ -0,0 +1,73 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Authentication;
|
||||
using Configuration;
|
||||
using DownstreamRouteFinder;
|
||||
using Errors;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
|
||||
public class AuthenticationMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
private readonly IApplicationBuilder _app;
|
||||
private readonly IAuthenticationHandlerFactory _authHandlerFactory;
|
||||
|
||||
public AuthenticationMiddleware(RequestDelegate next, IApplicationBuilder app,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository, IAuthenticationHandlerFactory authHandlerFactory)
|
||||
: base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
_authHandlerFactory = authHandlerFactory;
|
||||
_app = app;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var downstreamRoute = _scopedRequestDataRepository.Get<DownstreamRoute>("DownstreamRoute");
|
||||
|
||||
if (downstreamRoute.IsError)
|
||||
{
|
||||
SetPipelineError(downstreamRoute.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsAuthenticatedRoute(downstreamRoute.Data.ReRoute))
|
||||
{
|
||||
var authenticationNext = _authHandlerFactory.Get(_app, downstreamRoute.Data.ReRoute.AuthenticationOptions);
|
||||
|
||||
if (!authenticationNext.IsError)
|
||||
{
|
||||
await authenticationNext.Data.Handler.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPipelineError(authenticationNext.Errors);
|
||||
}
|
||||
|
||||
if (context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPipelineError(new List<Error> {new UnauthenticatedError($"Request for authenticated route {context.Request.Path} by {context.User.Identity.Name} was unauthenticated")});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsAuthenticatedRoute(ReRoute reRoute)
|
||||
{
|
||||
return reRoute.IsAuthenticated;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class AuthenticationMiddlewareMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseAuthenticationMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<AuthenticationMiddleware>(builder);
|
||||
}
|
||||
}
|
||||
}
|
23
src/Ocelot.Library/Middleware/ClaimsParserMiddleware.cs
Normal file
23
src/Ocelot.Library/Middleware/ClaimsParserMiddleware.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
|
||||
public class ClaimsParserMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public ClaimsParserMiddleware(RequestDelegate next, IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
: base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using DownstreamRouteFinder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
|
||||
public class DownstreamRouteFinderMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
|
||||
public DownstreamRouteFinderMiddleware(RequestDelegate next,
|
||||
IDownstreamRouteFinder downstreamRouteFinder,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
:base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_downstreamRouteFinder = downstreamRouteFinder;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var upstreamUrlPath = context.Request.Path.ToString();
|
||||
|
||||
var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);
|
||||
|
||||
if (downstreamRoute.IsError)
|
||||
{
|
||||
SetPipelineError(downstreamRoute.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
_scopedRequestDataRepository.Add("DownstreamRoute", downstreamRoute.Data);
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class DownstreamRouteFinderMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseDownstreamRouteFinderMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<DownstreamRouteFinderMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using DownstreamRouteFinder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
using UrlTemplateReplacer;
|
||||
|
||||
public class DownstreamUrlCreatorMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IDownstreamUrlTemplateVariableReplacer _urlReplacer;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
|
||||
public DownstreamUrlCreatorMiddleware(RequestDelegate next,
|
||||
IDownstreamUrlTemplateVariableReplacer urlReplacer,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
:base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_urlReplacer = urlReplacer;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var downstreamRoute = _scopedRequestDataRepository.Get<DownstreamRoute>("DownstreamRoute");
|
||||
|
||||
if (downstreamRoute.IsError)
|
||||
{
|
||||
SetPipelineError(downstreamRoute.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
var downstreamUrl = _urlReplacer.ReplaceTemplateVariables(downstreamRoute.Data);
|
||||
|
||||
if (downstreamUrl.IsError)
|
||||
{
|
||||
SetPipelineError(downstreamUrl.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
_scopedRequestDataRepository.Add("DownstreamUrl", downstreamUrl.Data);
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class DownstreamUrlCreatorMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseDownstreamUrlCreatorMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<DownstreamUrlCreatorMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
using RequestBuilder;
|
||||
|
||||
public class HttpRequestBuilderMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
private readonly IRequestBuilder _requestBuilder;
|
||||
|
||||
public HttpRequestBuilderMiddleware(RequestDelegate next,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository,
|
||||
IRequestBuilder requestBuilder)
|
||||
:base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
_requestBuilder = requestBuilder;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var downstreamUrl = _scopedRequestDataRepository.Get<string>("DownstreamUrl");
|
||||
|
||||
if (downstreamUrl.IsError)
|
||||
{
|
||||
SetPipelineError(downstreamUrl.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
var request = await _requestBuilder
|
||||
.Build(context.Request.Method, downstreamUrl.Data, context.Request.Body,
|
||||
context.Request.Headers, context.Request.Cookies, context.Request.QueryString.Value, context.Request.ContentType);
|
||||
|
||||
if (request.IsError)
|
||||
{
|
||||
SetPipelineError(request.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
_scopedRequestDataRepository.Add("Request", request.Data);
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class HttpRequestBuilderMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseHttpRequestBuilderMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<HttpRequestBuilderMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
46
src/Ocelot.Library/Middleware/HttpRequesterMiddleware.cs
Normal file
46
src/Ocelot.Library/Middleware/HttpRequesterMiddleware.cs
Normal file
@ -0,0 +1,46 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
using RequestBuilder;
|
||||
using Requester;
|
||||
|
||||
public class HttpRequesterMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IHttpRequester _requester;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
|
||||
public HttpRequesterMiddleware(RequestDelegate next,
|
||||
IHttpRequester requester,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
:base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_requester = requester;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var request = _scopedRequestDataRepository.Get<Request>("Request");
|
||||
|
||||
if (request.IsError)
|
||||
{
|
||||
SetPipelineError(request.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
var response = await _requester.GetResponse(request.Data);
|
||||
|
||||
if (response.IsError)
|
||||
{
|
||||
SetPipelineError(response.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
_scopedRequestDataRepository.Add("Response", response.Data);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class HttpRequesterMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseHttpRequesterMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<HttpRequesterMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
55
src/Ocelot.Library/Middleware/HttpResponderMiddleware.cs
Normal file
55
src/Ocelot.Library/Middleware/HttpResponderMiddleware.cs
Normal file
@ -0,0 +1,55 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Repository;
|
||||
using Responder;
|
||||
|
||||
public class HttpResponderMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IHttpResponder _responder;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
|
||||
|
||||
public HttpResponderMiddleware(RequestDelegate next,
|
||||
IHttpResponder responder,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository,
|
||||
IErrorsToHttpStatusCodeMapper codeMapper)
|
||||
:base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_responder = responder;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
_codeMapper = codeMapper;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
|
||||
if (PipelineError())
|
||||
{
|
||||
var errors = GetPipelineErrors();
|
||||
|
||||
var statusCode = _codeMapper.Map(errors);
|
||||
|
||||
if (!statusCode.IsError)
|
||||
{
|
||||
await _responder.CreateErrorResponse(context, statusCode.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _responder.CreateErrorResponse(context, 500);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var response = _scopedRequestDataRepository.Get<HttpResponseMessage>("Response");
|
||||
|
||||
await _responder.CreateResponse(context, response.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class HttpResponderMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseHttpResponderMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<HttpResponderMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
34
src/Ocelot.Library/Middleware/OcelotMiddleware.cs
Normal file
34
src/Ocelot.Library/Middleware/OcelotMiddleware.cs
Normal file
@ -0,0 +1,34 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Errors;
|
||||
using Repository;
|
||||
|
||||
public abstract class OcelotMiddleware
|
||||
{
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
|
||||
protected OcelotMiddleware(IScopedRequestDataRepository scopedRequestDataRepository)
|
||||
{
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
}
|
||||
|
||||
public void SetPipelineError(List<Error> errors)
|
||||
{
|
||||
_scopedRequestDataRepository.Add("OcelotMiddlewareError", true);
|
||||
_scopedRequestDataRepository.Add("OcelotMiddlewareErrors", errors);
|
||||
}
|
||||
|
||||
public bool PipelineError()
|
||||
{
|
||||
var response = _scopedRequestDataRepository.Get<bool>("OcelotMiddlewareError");
|
||||
return response.Data;
|
||||
}
|
||||
|
||||
public List<Error> GetPipelineErrors()
|
||||
{
|
||||
var response = _scopedRequestDataRepository.Get<List<Error>>("OcelotMiddlewareErrors");
|
||||
return response.Data;
|
||||
}
|
||||
}
|
||||
}
|
24
src/Ocelot.Library/Middleware/OcelotMiddlewareExtensions.cs
Normal file
24
src/Ocelot.Library/Middleware/OcelotMiddlewareExtensions.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public static class OcelotMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder)
|
||||
{
|
||||
builder.UseHttpResponderMiddleware();
|
||||
|
||||
builder.UseDownstreamRouteFinderMiddleware();
|
||||
|
||||
builder.UseAuthenticationMiddleware();
|
||||
|
||||
builder.UseDownstreamUrlCreatorMiddleware();
|
||||
|
||||
builder.UseHttpRequestBuilderMiddleware();
|
||||
|
||||
builder.UseHttpRequesterMiddleware();
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
11
src/Ocelot.Library/Middleware/UnauthenticatedError.cs
Normal file
11
src/Ocelot.Library/Middleware/UnauthenticatedError.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Ocelot.Library.Middleware
|
||||
{
|
||||
using Errors;
|
||||
|
||||
public class UnauthenticatedError : Error
|
||||
{
|
||||
public UnauthenticatedError(string message) : base(message, OcelotErrorCode.UnauthenticatedError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user