mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 14:02:49 +08:00
started adding route authorisation
This commit is contained in:
parent
cb4b000b21
commit
0221ee9ccb
@ -4,5 +4,7 @@ echo Building Ocelot
|
||||
dotnet restore src/Ocelot
|
||||
dotnet build src/Ocelot
|
||||
dotnet publish src/Ocelot -o artifacts/
|
||||
dotnet pack src/Ocelot/project.json --output nupkgs/
|
||||
|
||||
|
||||
|
||||
|
53
src/Ocelot/Authorisation/AuthorisationMiddleware.cs
Normal file
53
src/Ocelot/Authorisation/AuthorisationMiddleware.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.ScopedData;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
public class AuthorisationMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
|
||||
private readonly IAuthoriser _authoriser;
|
||||
|
||||
public AuthorisationMiddleware(RequestDelegate next,
|
||||
IScopedRequestDataRepository scopedRequestDataRepository,
|
||||
IAuthoriser authoriser)
|
||||
: base(scopedRequestDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_scopedRequestDataRepository = scopedRequestDataRepository;
|
||||
_authoriser = authoriser;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
var downstreamRoute = _scopedRequestDataRepository.Get<DownstreamRoute>("DownstreamRoute");
|
||||
|
||||
if (downstreamRoute.IsError)
|
||||
{
|
||||
SetPipelineError(downstreamRoute.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
var authorised = _authoriser.Authorise(context.User, new RouteClaimsRequirement());
|
||||
|
||||
if (authorised)
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
//set an error
|
||||
SetPipelineError(new List<Error>
|
||||
{
|
||||
new UnauthorisedError($"{context.User.Identity.Name} unable to access {downstreamRoute.Data.ReRoute.UpstreamTemplate}")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
public static class AuthorisationMiddlewareMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseAuthorisationMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<AuthorisationMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
12
src/Ocelot/Authorisation/ClaimsAuthoriser.cs
Normal file
12
src/Ocelot/Authorisation/ClaimsAuthoriser.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
public class ClaimsAuthoriser : IAuthoriser
|
||||
{
|
||||
public bool Authorise(ClaimsPrincipal claimsPrincipal, RouteClaimsRequirement routeClaimsRequirement)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
10
src/Ocelot/Authorisation/IAuthoriser.cs
Normal file
10
src/Ocelot/Authorisation/IAuthoriser.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
public interface IAuthoriser
|
||||
{
|
||||
bool Authorise(ClaimsPrincipal claimsPrincipal,
|
||||
RouteClaimsRequirement routeClaimsRequirement);
|
||||
}
|
||||
}
|
11
src/Ocelot/Authorisation/RouteClaimsRequirement.cs
Normal file
11
src/Ocelot/Authorisation/RouteClaimsRequirement.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
public class RouteClaimsRequirement
|
||||
{
|
||||
}
|
||||
}
|
12
src/Ocelot/Authorisation/UnauthorisedError.cs
Normal file
12
src/Ocelot/Authorisation/UnauthorisedError.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
public class UnauthorisedError : Error
|
||||
{
|
||||
public UnauthorisedError(string message)
|
||||
: base(message, OcelotErrorCode.UnauthorizedError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Authentication.Handler.Creator;
|
||||
using Ocelot.Authentication.Handler.Factory;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Parser;
|
||||
using Ocelot.Configuration.Provider;
|
||||
@ -45,6 +47,7 @@ namespace Ocelot.DependencyInjection
|
||||
services.AddLogging();
|
||||
|
||||
// ocelot services.
|
||||
services.AddSingleton<IAuthoriser, ClaimsAuthoriser>();
|
||||
services.AddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
||||
services.AddSingleton<IClaimsParser, ClaimsParser>();
|
||||
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||
|
@ -14,6 +14,7 @@
|
||||
CannotFindClaimError,
|
||||
ParsingConfigurationHeaderError,
|
||||
NoInstructionsError,
|
||||
InstructionNotForClaimsError
|
||||
InstructionNotForClaimsError,
|
||||
UnauthorizedError
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Ocelot.Authentication.Middleware;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||
using Ocelot.HeaderBuilder.Middleware;
|
||||
@ -19,6 +20,8 @@ namespace Ocelot.Middleware
|
||||
|
||||
builder.UseAuthenticationMiddleware();
|
||||
|
||||
//builder.UseAuthorisationMiddleware();
|
||||
|
||||
builder.UseHttpRequestHeadersBuilderMiddleware();
|
||||
|
||||
builder.UseDownstreamUrlCreatorMiddleware();
|
||||
|
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.ScopedData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Authorization
|
||||
{
|
||||
public class AuthorizationMiddlewareTests : IDisposable
|
||||
{
|
||||
private readonly Mock<IScopedRequestDataRepository> _scopedRepository;
|
||||
private readonly Mock<IAuthoriser> _authService;
|
||||
private readonly string _url;
|
||||
private readonly TestServer _server;
|
||||
private readonly HttpClient _client;
|
||||
private HttpResponseMessage _result;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public AuthorizationMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_scopedRepository = new Mock<IScopedRequestDataRepository>();
|
||||
_authService = new Mock<IAuthoriser>();
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton(_authService.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
.UseUrls(_url)
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.UseUrls(_url)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseAuthorisationMiddleware();
|
||||
});
|
||||
|
||||
_server = new TestServer(builder);
|
||||
_client = _server.CreateClient();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<TemplateVariableNameAndValue>(), new ReRouteBuilder().Build())))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAuthServiceIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheAuthServiceIsCalledCorrectly()
|
||||
{
|
||||
_authService
|
||||
.Verify(x => x.Authorise(It.IsAny<ClaimsPrincipal>(),
|
||||
It.IsAny<RouteClaimsRequirement>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
_scopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddleware()
|
||||
{
|
||||
_result = _client.GetAsync(_url).Result;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_client.Dispose();
|
||||
_server.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user