mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 18:48:15 +08:00

committed by
Thiago Loureiro

parent
340d0de233
commit
639011bc62
@ -1,6 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
@ -15,8 +22,11 @@ namespace Ocelot.Authorisation
|
||||
_claimsParser = claimsParser;
|
||||
}
|
||||
|
||||
public Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, Dictionary<string, string> routeClaimsRequirement)
|
||||
{
|
||||
public Response<bool> Authorise(
|
||||
ClaimsPrincipal claimsPrincipal,
|
||||
Dictionary<string, string> routeClaimsRequirement,
|
||||
List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues
|
||||
){
|
||||
foreach (var required in routeClaimsRequirement)
|
||||
{
|
||||
var values = _claimsParser.GetValuesByClaimType(claimsPrincipal.Claims, required.Key);
|
||||
@ -27,12 +37,50 @@ namespace Ocelot.Authorisation
|
||||
}
|
||||
|
||||
if (values.Data != null)
|
||||
{
|
||||
var authorised = values.Data.Contains(required.Value);
|
||||
if (!authorised)
|
||||
{
|
||||
// dynamic claim
|
||||
var match = Regex.Match(required.Value, @"^{(?<variable>.+)}$");
|
||||
if (match.Success)
|
||||
{
|
||||
return new ErrorResponse<bool>(new ClaimValueNotAuthorisedError(
|
||||
$"claim value: {string.Join(", ", values.Data)} is not the same as required value: {required.Value} for type: {required.Key}"));
|
||||
var variableName = match.Captures[0].Value;
|
||||
|
||||
var matchingPlaceholders = urlPathPlaceholderNameAndValues.Where(p => p.Name.Equals(variableName)).Take(2).ToArray();
|
||||
if (matchingPlaceholders.Length == 1)
|
||||
{
|
||||
// match
|
||||
var actualValue = matchingPlaceholders[0].Value;
|
||||
var authorised = values.Data.Contains(actualValue);
|
||||
if (!authorised)
|
||||
{
|
||||
return new ErrorResponse<bool>(new ClaimValueNotAuthorisedError(
|
||||
$"dynamic claim value for {variableName} of {string.Join(", ", values.Data)} is not the same as required value: {actualValue}"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// config error
|
||||
if (matchingPlaceholders.Length == 0)
|
||||
{
|
||||
return new ErrorResponse<bool>(new ClaimValueNotAuthorisedError(
|
||||
$"config error: requires variable claim value: {variableName} placeholders does not contain that variable: {string.Join(", ", urlPathPlaceholderNameAndValues.Select(p=>p.Name))}"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ErrorResponse<bool>(new ClaimValueNotAuthorisedError(
|
||||
$"config error: requires variable claim value: {required.Value} but placeholders are ambiguous: {string.Join(", ", urlPathPlaceholderNameAndValues.Where(p=>p.Name.Equals(variableName)).Select(p => p.Value))}"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// static claim
|
||||
var authorised = values.Data.Contains(required.Value);
|
||||
if (!authorised)
|
||||
{
|
||||
return new ErrorResponse<bool>(new ClaimValueNotAuthorisedError(
|
||||
$"claim value: {string.Join(", ", values.Data)} is not the same as required value: {required.Value} for type: {required.Key}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1,5 +1,9 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
|
||||
namespace Ocelot.Authorisation
|
||||
{
|
||||
@ -7,6 +11,10 @@ namespace Ocelot.Authorisation
|
||||
|
||||
public interface IClaimsAuthoriser
|
||||
{
|
||||
Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, Dictionary<string, string> routeClaimsRequirement);
|
||||
Response<bool> Authorise(
|
||||
ClaimsPrincipal claimsPrincipal,
|
||||
Dictionary<string, string> routeClaimsRequirement,
|
||||
List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -57,8 +57,8 @@
|
||||
if (IsAuthorisedRoute(context.DownstreamReRoute))
|
||||
{
|
||||
Logger.LogInformation("route is authorised");
|
||||
|
||||
var authorised = _claimsAuthoriser.Authorise(context.HttpContext.User, context.DownstreamReRoute.RouteClaimsRequirement);
|
||||
|
||||
var authorised = _claimsAuthoriser.Authorise(context.HttpContext.User, context.DownstreamReRoute.RouteClaimsRequirement, context.TemplatePlaceholderNameAndValues);
|
||||
|
||||
if (authorised.IsError)
|
||||
{
|
||||
|
Reference in New Issue
Block a user