Skip to content

Commit

Permalink
Merge pull request #22 from Sagilio/master
Browse files Browse the repository at this point in the history
feat: Add DefaultAuthenticationSchemes option
  • Loading branch information
hsluoyz committed Mar 15, 2021
2 parents 84907ca + 395c0c7 commit 8591b1b
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 46 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Dry-run semantic-release
- name: Run semantic-release
run: |
export PATH=$PATH:$(yarn global bin)
yarn global add semantic-release@17.2.4
semantic-release -d
semantic-release
release-build-version:
runs-on: windows-latest
Expand Down
3 changes: 2 additions & 1 deletion src/Casbin.AspNetCore.Core/CasbinAuthorizationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ public class CasbinAuthorizationOptions
public string? DefaultModelPath { get; set; }
public string? DefaultPolicyPath { get; set; }
public Func<IServiceProvider, Model?, Enforcer>? DefaultEnforcerFactory { get; set; }
public string PreferSubClaimType { get; set; } = ClaimTypes.NameIdentifier;
public string? DefaultAuthenticationSchemes { get; set; }
public IRequestTransformer? DefaultRequestTransformer { get; set; }
public string PreferSubClaimType { get; set; } = ClaimTypes.NameIdentifier;
public bool AllowAnyone { get; set; } = false;
}
}
8 changes: 4 additions & 4 deletions src/Casbin.AspNetCore.Core/CoreServiceCollectionExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public static class CoreServiceCollectionExtension
services.TryAddSingleton<ICasbinAuthorizationContextFactory, DefaultCasbinAuthorizationContextFactory>();
services.TryAddScoped<IEnforceService, DefaultEnforcerService>();
services.TryAddSingleton<IRequestTransformersCache, RequestTransformersCache>();
services.AddScoped<IAuthorizationHandler, CasbinAuthorizationHandler>();
services.AddSingleton<IRequestTransformer, BasicRequestTransformer>();
services.AddSingleton<IRequestTransformer, RbacRequestTransformer>();
services.AddSingleton<IRequestTransformer, KeyMatchRequestTransformer>();
services.TryAddScoped<IAuthorizationHandler, CasbinAuthorizationHandler>();
services.TryAddSingleton<IRequestTransformer, BasicRequestTransformer>();
services.TryAddSingleton<IRequestTransformer, RbacRequestTransformer>();
services.TryAddSingleton<IRequestTransformer, KeyMatchRequestTransformer>();
services.AddAuthorizationCore();
return services;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;

namespace Casbin.AspNetCore.Authorization
{
public interface ICasbinAuthorizationPolicyProvider
{
public AuthorizationPolicy GetAuthorizationPolicy(IEnumerable<ICasbinAuthorizationData> authorizationData);
}
}
10 changes: 0 additions & 10 deletions src/Casbin.AspNetCore/Abstractions/ICasbinPolicyCreator.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Casbin.AspNetCore/AppBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static IApplicationBuilder UseCasbinAuthorization(this IApplicationBuilde

private static void VerifyServicesRegistered(IApplicationBuilder app)
{
if (app.ApplicationServices.GetService(typeof(ICasbinPolicyCreator)) == null)
if (app.ApplicationServices.GetService(typeof(ICasbinAuthorizationPolicyProvider)) == null)
{
throw new InvalidOperationException($"Unable to find the required services. Please add all the required services by calling '{nameof(IServiceCollection)}.{nameof(ServiceCollectionExtension.AddCasbinAuthorization)}' inside the call to 'ConfigureServices(...)' in the application startup code.");
}
Expand Down
6 changes: 3 additions & 3 deletions src/Casbin.AspNetCore/CasbinAuthorizationMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public class CasbinAuthorizationMiddleware
private static readonly object s_casbinAuthorizationMiddlewareWithEndpointInvokedValue = new();

private readonly RequestDelegate _next;
private readonly ICasbinPolicyCreator _policyCreator;
private readonly ICasbinAuthorizationPolicyProvider _policyCreator;
private readonly IOptions<CasbinAuthorizationOptions> _options;

public CasbinAuthorizationMiddleware(RequestDelegate next, ICasbinPolicyCreator policyCreator, IOptions<CasbinAuthorizationOptions> options)
public CasbinAuthorizationMiddleware(RequestDelegate next, ICasbinAuthorizationPolicyProvider policyCreator, IOptions<CasbinAuthorizationOptions> options)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_policyCreator = policyCreator ?? throw new ArgumentNullException(nameof(policyCreator));
Expand Down Expand Up @@ -48,7 +48,7 @@ public async Task Invoke(HttpContext context)
}

bool allowAnyone = _options.Value.AllowAnyone;
var policy = _policyCreator.Create(authorizeData);
var policy = _policyCreator.GetAuthorizationPolicy(authorizeData);

AuthenticateResult? authenticateResult = null;
if (allowAnyone is false)
Expand Down
64 changes: 46 additions & 18 deletions src/Casbin.AspNetCore/Policy/CasbinPolicyCreator.cs
Original file line number Diff line number Diff line change
@@ -1,49 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Microsoft.JSInterop;

namespace Casbin.AspNetCore.Authorization.Policy
{
public class CasbinPolicyCreator : ICasbinPolicyCreator
public class DefaultCasbinAuthorizationPolicyProvider : ICasbinAuthorizationPolicyProvider
{
public CasbinPolicyCreator()
public DefaultCasbinAuthorizationPolicyProvider(IOptions<CasbinAuthorizationOptions> options)
{
_emptyPolicy = new AuthorizationPolicy(_casbinAuthorizationRequirements, Array.Empty<string>());
if (options is null)
{
throw new NullReferenceException(nameof(options));
}

string? defaultAuthenticationSchemes = options.Value.DefaultAuthenticationSchemes;
ICollection<string> authenticationSchemes = new List<string>();
if (defaultAuthenticationSchemes is not null)
{
AddAuthenticationSchemes(authenticationSchemes, defaultAuthenticationSchemes);
}
_defaultPolicy = new AuthorizationPolicy(_casbinAuthorizationRequirements, authenticationSchemes);
}

private readonly IEnumerable<IAuthorizationRequirement> _casbinAuthorizationRequirements =
new []{CasbinAuthorizationRequirement.Requirement};
new[] { CasbinAuthorizationRequirement.Requirement };

private readonly AuthorizationPolicy _emptyPolicy;
private readonly AuthorizationPolicy _defaultPolicy;

public AuthorizationPolicy Create(IEnumerable<ICasbinAuthorizationData> authorizationData)
public AuthorizationPolicy GetAuthorizationPolicy(IEnumerable<ICasbinAuthorizationData> authorizationData)
{
if (authorizationData is null)
{
throw new ArgumentNullException(nameof(authorizationData));
}

IList<string>? authenticationSchemes = null;
ICollection<string>? authenticationSchemes = null;
foreach (var data in authorizationData)
{
string[]? authTypesSplit = data.AuthenticationSchemes?.Split(',');
if (authTypesSplit is null || authTypesSplit.Length > 0 is false)
if (string.IsNullOrWhiteSpace(data.AuthenticationSchemes))
{
return _emptyPolicy;
continue;
}

authenticationSchemes ??= new List<string>();
authenticationSchemes = _defaultPolicy.AuthenticationSchemes as ICollection<string> ??
_defaultPolicy.AuthenticationSchemes.ToList();

AddAuthenticationSchemes(authenticationSchemes, data.AuthenticationSchemes);
}

foreach (var authType in authTypesSplit)
return authenticationSchemes is not null
? new AuthorizationPolicy(_casbinAuthorizationRequirements, authenticationSchemes)
: _defaultPolicy;
}

private static void AddAuthenticationSchemes(ICollection<string> authenticationSchemes,
string authenticationSchemesString)
{
string[] authTypesSplit = authenticationSchemesString.Split(',');
if (authTypesSplit.Length == 0)
{
return;
}

foreach (var authType in authTypesSplit)
{
if (string.IsNullOrWhiteSpace(authType) is false)
{
if (string.IsNullOrWhiteSpace(authType) is false)
{
authenticationSchemes.Add(authType.Trim());
}
authenticationSchemes.Add(authType.Trim());
}
}

return authenticationSchemes is null ? _emptyPolicy : new AuthorizationPolicy(_casbinAuthorizationRequirements, authenticationSchemes);
}
}
}
2 changes: 1 addition & 1 deletion src/Casbin.AspNetCore/ServiceCollectionExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal static IServiceCollection AddCasbinPolicy(this IServiceCollection servi
ServiceLifetime defaultModelProviderLifeTime = ServiceLifetime.Scoped)
{
services.TryAddTransient<ICasbinEvaluator, CasbinEvaluator>();
services.TryAddSingleton<ICasbinPolicyCreator, CasbinPolicyCreator>();
services.TryAddSingleton<ICasbinAuthorizationPolicyProvider, DefaultCasbinAuthorizationPolicyProvider>();
services.TryAddSingleton<ICasbinAuthorizationMiddlewareResultHandler, CasbinAuthorizationMiddlewareResultHandler>();
services.AddCasbinAuthorizationCore(configureOptions, defaultEnforcerProviderLifeTime, defaultModelProviderLifeTime);
return services;
Expand Down
11 changes: 5 additions & 6 deletions test/Casbin.AspNetCore.Tests/CasbinEvaluatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Casbin.AspNetCore.Tests.Fixtures;
using Casbin.AspNetCore.Tests.Utilities;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

Expand All @@ -16,14 +15,14 @@ namespace Casbin.AspNetCore.Tests
public class CasbinEvaluatorTest : IClassFixture<TestServerFixture>
{
private readonly IServiceProvider _serviceProvider;
private readonly ICasbinPolicyCreator _casbinPolicyCreator;
private readonly ICasbinAuthorizationPolicyProvider _casbinPolicyCreator;
private readonly ICasbinAuthorizationContextFactory _casbinAuthorizationContextFactory;
private const string s_defaultScheme = "context.User";

public CasbinEvaluatorTest(TestServerFixture testServerFixture)
{
_serviceProvider = testServerFixture.TestServer.Services;
_casbinPolicyCreator = _serviceProvider.GetRequiredService<ICasbinPolicyCreator>();
_casbinPolicyCreator = _serviceProvider.GetRequiredService<ICasbinAuthorizationPolicyProvider>();
_casbinAuthorizationContextFactory = _serviceProvider.GetRequiredService<ICasbinAuthorizationContextFactory>();
}

Expand All @@ -47,7 +46,7 @@ public CasbinEvaluatorTest(TestServerFixture testServerFixture)
var casbinEvaluator = _serviceProvider.GetRequiredService<ICasbinEvaluator>();
var casbinContext = _casbinAuthorizationContextFactory.CreateContext(
new CasbinAuthorizeAttribute(resource, action), httpContext);
var policy = _casbinPolicyCreator.Create(casbinContext.AuthorizationData);
var policy = _casbinPolicyCreator.GetAuthorizationPolicy(casbinContext.AuthorizationData);
var result = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, s_defaultScheme));

// Act
Expand Down Expand Up @@ -80,7 +79,7 @@ public CasbinEvaluatorTest(TestServerFixture testServerFixture)
var casbinEvaluator = _serviceProvider.GetRequiredService<ICasbinEvaluator>();
var casbinContext = _casbinAuthorizationContextFactory.CreateContext(
new CasbinAuthorizeAttribute(resource, action) { Issuer = testIssuer }, httpContext);
var policy = _casbinPolicyCreator.Create(casbinContext.AuthorizationData);
var policy = _casbinPolicyCreator.GetAuthorizationPolicy(casbinContext.AuthorizationData);
var result = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, s_defaultScheme));

// Act
Expand Down Expand Up @@ -112,7 +111,7 @@ public CasbinEvaluatorTest(TestServerFixture testServerFixture)
var casbinContext = _casbinAuthorizationContextFactory.CreateContext(
new CasbinAuthorizeAttribute(resource, action) { PreferSubClaimType = testClaimType },
httpContext);
var policy = _casbinPolicyCreator.Create(casbinContext.AuthorizationData);
var policy = _casbinPolicyCreator.GetAuthorizationPolicy(casbinContext.AuthorizationData);
var result = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, s_defaultScheme));

// Act
Expand Down

0 comments on commit 8591b1b

Please sign in to comment.