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:
tom.pallister
2016-10-17 18:00:36 +01:00
parent ce84ad4fc2
commit 3d60602c7e
97 changed files with 614 additions and 508 deletions

View 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;
}
}
}

View File

@ -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);
}
}
}

View 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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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>();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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>();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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>();
}
}
}

View 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);
}
}
}

View File

@ -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>();
}
}
}

View 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);
}
}
}
}

View File

@ -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>();
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View File

@ -0,0 +1,11 @@
namespace Ocelot.Library.Middleware
{
using Errors;
public class UnauthenticatedError : Error
{
public UnauthenticatedError(string message) : base(message, OcelotErrorCode.UnauthenticatedError)
{
}
}
}