Skip to content

Commit 395c0c7

Browse files
committed
feat: Add DefaultAuthenticationSchemes option
Signed-off-by: Sagilio <Sagilio@outlook.com>
1 parent 84907ca commit 395c0c7

File tree

10 files changed

+74
-46
lines changed

10 files changed

+74
-46
lines changed

.github/workflows/build-and-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ jobs:
8383
- name: Checkout
8484
uses: actions/checkout@v2
8585

86-
- name: Dry-run semantic-release
86+
- name: Run semantic-release
8787
run: |
8888
export PATH=$PATH:$(yarn global bin)
8989
yarn global add semantic-release@17.2.4
90-
semantic-release -d
90+
semantic-release
9191
9292
release-build-version:
9393
runs-on: windows-latest

src/Casbin.AspNetCore.Core/CasbinAuthorizationOptions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ public class CasbinAuthorizationOptions
1010
public string? DefaultModelPath { get; set; }
1111
public string? DefaultPolicyPath { get; set; }
1212
public Func<IServiceProvider, Model?, Enforcer>? DefaultEnforcerFactory { get; set; }
13-
public string PreferSubClaimType { get; set; } = ClaimTypes.NameIdentifier;
13+
public string? DefaultAuthenticationSchemes { get; set; }
1414
public IRequestTransformer? DefaultRequestTransformer { get; set; }
15+
public string PreferSubClaimType { get; set; } = ClaimTypes.NameIdentifier;
1516
public bool AllowAnyone { get; set; } = false;
1617
}
1718
}

src/Casbin.AspNetCore.Core/CoreServiceCollectionExtension.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ public static IServiceCollection AddCasbinAuthorizationCore(
5050
services.TryAddSingleton<ICasbinAuthorizationContextFactory, DefaultCasbinAuthorizationContextFactory>();
5151
services.TryAddScoped<IEnforceService, DefaultEnforcerService>();
5252
services.TryAddSingleton<IRequestTransformersCache, RequestTransformersCache>();
53-
services.AddScoped<IAuthorizationHandler, CasbinAuthorizationHandler>();
54-
services.AddSingleton<IRequestTransformer, BasicRequestTransformer>();
55-
services.AddSingleton<IRequestTransformer, RbacRequestTransformer>();
56-
services.AddSingleton<IRequestTransformer, KeyMatchRequestTransformer>();
53+
services.TryAddScoped<IAuthorizationHandler, CasbinAuthorizationHandler>();
54+
services.TryAddSingleton<IRequestTransformer, BasicRequestTransformer>();
55+
services.TryAddSingleton<IRequestTransformer, RbacRequestTransformer>();
56+
services.TryAddSingleton<IRequestTransformer, KeyMatchRequestTransformer>();
5757
services.AddAuthorizationCore();
5858
return services;
5959
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Collections.Generic;
2+
using Microsoft.AspNetCore.Authorization;
3+
4+
namespace Casbin.AspNetCore.Authorization
5+
{
6+
public interface ICasbinAuthorizationPolicyProvider
7+
{
8+
public AuthorizationPolicy GetAuthorizationPolicy(IEnumerable<ICasbinAuthorizationData> authorizationData);
9+
}
10+
}

src/Casbin.AspNetCore/Abstractions/ICasbinPolicyCreator.cs

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/Casbin.AspNetCore/AppBuilderExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static IApplicationBuilder UseCasbinAuthorization(this IApplicationBuilde
2525

2626
private static void VerifyServicesRegistered(IApplicationBuilder app)
2727
{
28-
if (app.ApplicationServices.GetService(typeof(ICasbinPolicyCreator)) == null)
28+
if (app.ApplicationServices.GetService(typeof(ICasbinAuthorizationPolicyProvider)) == null)
2929
{
3030
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.");
3131
}

src/Casbin.AspNetCore/CasbinAuthorizationMiddleware.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ public class CasbinAuthorizationMiddleware
1515
private static readonly object s_casbinAuthorizationMiddlewareWithEndpointInvokedValue = new();
1616

1717
private readonly RequestDelegate _next;
18-
private readonly ICasbinPolicyCreator _policyCreator;
18+
private readonly ICasbinAuthorizationPolicyProvider _policyCreator;
1919
private readonly IOptions<CasbinAuthorizationOptions> _options;
2020

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

5050
bool allowAnyone = _options.Value.AllowAnyone;
51-
var policy = _policyCreator.Create(authorizeData);
51+
var policy = _policyCreator.GetAuthorizationPolicy(authorizeData);
5252

5353
AuthenticateResult? authenticateResult = null;
5454
if (allowAnyone is false)
Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,77 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using Microsoft.AspNetCore.Authorization;
5+
using Microsoft.Extensions.Options;
6+
using Microsoft.JSInterop;
47

58
namespace Casbin.AspNetCore.Authorization.Policy
69
{
7-
public class CasbinPolicyCreator : ICasbinPolicyCreator
10+
public class DefaultCasbinAuthorizationPolicyProvider : ICasbinAuthorizationPolicyProvider
811
{
9-
public CasbinPolicyCreator()
12+
public DefaultCasbinAuthorizationPolicyProvider(IOptions<CasbinAuthorizationOptions> options)
1013
{
11-
_emptyPolicy = new AuthorizationPolicy(_casbinAuthorizationRequirements, Array.Empty<string>());
14+
if (options is null)
15+
{
16+
throw new NullReferenceException(nameof(options));
17+
}
18+
19+
string? defaultAuthenticationSchemes = options.Value.DefaultAuthenticationSchemes;
20+
ICollection<string> authenticationSchemes = new List<string>();
21+
if (defaultAuthenticationSchemes is not null)
22+
{
23+
AddAuthenticationSchemes(authenticationSchemes, defaultAuthenticationSchemes);
24+
}
25+
_defaultPolicy = new AuthorizationPolicy(_casbinAuthorizationRequirements, authenticationSchemes);
1226
}
1327

1428
private readonly IEnumerable<IAuthorizationRequirement> _casbinAuthorizationRequirements =
15-
new []{CasbinAuthorizationRequirement.Requirement};
29+
new[] { CasbinAuthorizationRequirement.Requirement };
1630

17-
private readonly AuthorizationPolicy _emptyPolicy;
31+
private readonly AuthorizationPolicy _defaultPolicy;
1832

19-
public AuthorizationPolicy Create(IEnumerable<ICasbinAuthorizationData> authorizationData)
33+
public AuthorizationPolicy GetAuthorizationPolicy(IEnumerable<ICasbinAuthorizationData> authorizationData)
2034
{
2135
if (authorizationData is null)
2236
{
2337
throw new ArgumentNullException(nameof(authorizationData));
2438
}
2539

26-
IList<string>? authenticationSchemes = null;
40+
ICollection<string>? authenticationSchemes = null;
2741
foreach (var data in authorizationData)
2842
{
29-
string[]? authTypesSplit = data.AuthenticationSchemes?.Split(',');
30-
if (authTypesSplit is null || authTypesSplit.Length > 0 is false)
43+
if (string.IsNullOrWhiteSpace(data.AuthenticationSchemes))
3144
{
32-
return _emptyPolicy;
45+
continue;
3346
}
3447

35-
authenticationSchemes ??= new List<string>();
48+
authenticationSchemes = _defaultPolicy.AuthenticationSchemes as ICollection<string> ??
49+
_defaultPolicy.AuthenticationSchemes.ToList();
50+
51+
AddAuthenticationSchemes(authenticationSchemes, data.AuthenticationSchemes);
52+
}
3653

37-
foreach (var authType in authTypesSplit)
54+
return authenticationSchemes is not null
55+
? new AuthorizationPolicy(_casbinAuthorizationRequirements, authenticationSchemes)
56+
: _defaultPolicy;
57+
}
58+
59+
private static void AddAuthenticationSchemes(ICollection<string> authenticationSchemes,
60+
string authenticationSchemesString)
61+
{
62+
string[] authTypesSplit = authenticationSchemesString.Split(',');
63+
if (authTypesSplit.Length == 0)
64+
{
65+
return;
66+
}
67+
68+
foreach (var authType in authTypesSplit)
69+
{
70+
if (string.IsNullOrWhiteSpace(authType) is false)
3871
{
39-
if (string.IsNullOrWhiteSpace(authType) is false)
40-
{
41-
authenticationSchemes.Add(authType.Trim());
42-
}
72+
authenticationSchemes.Add(authType.Trim());
4373
}
4474
}
45-
46-
return authenticationSchemes is null ? _emptyPolicy : new AuthorizationPolicy(_casbinAuthorizationRequirements, authenticationSchemes);
4775
}
4876
}
4977
}

src/Casbin.AspNetCore/ServiceCollectionExtension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static IServiceCollection AddCasbinAuthorization(this IServiceCollection
3030
ServiceLifetime defaultModelProviderLifeTime = ServiceLifetime.Scoped)
3131
{
3232
services.TryAddTransient<ICasbinEvaluator, CasbinEvaluator>();
33-
services.TryAddSingleton<ICasbinPolicyCreator, CasbinPolicyCreator>();
33+
services.TryAddSingleton<ICasbinAuthorizationPolicyProvider, DefaultCasbinAuthorizationPolicyProvider>();
3434
services.TryAddSingleton<ICasbinAuthorizationMiddlewareResultHandler, CasbinAuthorizationMiddlewareResultHandler>();
3535
services.AddCasbinAuthorizationCore(configureOptions, defaultEnforcerProviderLifeTime, defaultModelProviderLifeTime);
3636
return services;

test/Casbin.AspNetCore.Tests/CasbinEvaluatorTest.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using Casbin.AspNetCore.Tests.Fixtures;
88
using Casbin.AspNetCore.Tests.Utilities;
99
using Microsoft.AspNetCore.Authentication;
10-
using Microsoft.AspNetCore.Http;
1110
using Microsoft.Extensions.DependencyInjection;
1211
using Xunit;
1312

@@ -16,14 +15,14 @@ namespace Casbin.AspNetCore.Tests
1615
public class CasbinEvaluatorTest : IClassFixture<TestServerFixture>
1716
{
1817
private readonly IServiceProvider _serviceProvider;
19-
private readonly ICasbinPolicyCreator _casbinPolicyCreator;
18+
private readonly ICasbinAuthorizationPolicyProvider _casbinPolicyCreator;
2019
private readonly ICasbinAuthorizationContextFactory _casbinAuthorizationContextFactory;
2120
private const string s_defaultScheme = "context.User";
2221

2322
public CasbinEvaluatorTest(TestServerFixture testServerFixture)
2423
{
2524
_serviceProvider = testServerFixture.TestServer.Services;
26-
_casbinPolicyCreator = _serviceProvider.GetRequiredService<ICasbinPolicyCreator>();
25+
_casbinPolicyCreator = _serviceProvider.GetRequiredService<ICasbinAuthorizationPolicyProvider>();
2726
_casbinAuthorizationContextFactory = _serviceProvider.GetRequiredService<ICasbinAuthorizationContextFactory>();
2827
}
2928

@@ -47,7 +46,7 @@ public async Task ShouldBasicAuthorizeAsync(
4746
var casbinEvaluator = _serviceProvider.GetRequiredService<ICasbinEvaluator>();
4847
var casbinContext = _casbinAuthorizationContextFactory.CreateContext(
4948
new CasbinAuthorizeAttribute(resource, action), httpContext);
50-
var policy = _casbinPolicyCreator.Create(casbinContext.AuthorizationData);
49+
var policy = _casbinPolicyCreator.GetAuthorizationPolicy(casbinContext.AuthorizationData);
5150
var result = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, s_defaultScheme));
5251

5352
// Act
@@ -80,7 +79,7 @@ public async Task ShouldBasicAuthorizeWhenSpecIssuerAsync(
8079
var casbinEvaluator = _serviceProvider.GetRequiredService<ICasbinEvaluator>();
8180
var casbinContext = _casbinAuthorizationContextFactory.CreateContext(
8281
new CasbinAuthorizeAttribute(resource, action) { Issuer = testIssuer }, httpContext);
83-
var policy = _casbinPolicyCreator.Create(casbinContext.AuthorizationData);
82+
var policy = _casbinPolicyCreator.GetAuthorizationPolicy(casbinContext.AuthorizationData);
8483
var result = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, s_defaultScheme));
8584

8685
// Act
@@ -112,7 +111,7 @@ public async Task ShouldBasicAuthorizeWhenSpecSubClaimTypeAsync(
112111
var casbinContext = _casbinAuthorizationContextFactory.CreateContext(
113112
new CasbinAuthorizeAttribute(resource, action) { PreferSubClaimType = testClaimType },
114113
httpContext);
115-
var policy = _casbinPolicyCreator.Create(casbinContext.AuthorizationData);
114+
var policy = _casbinPolicyCreator.GetAuthorizationPolicy(casbinContext.AuthorizationData);
116115
var result = AuthenticateResult.Success(new AuthenticationTicket(httpContext.User, s_defaultScheme));
117116

118117
// Act

0 commit comments

Comments
 (0)