87 lines
No EOL
2.8 KiB
C#
87 lines
No EOL
2.8 KiB
C#
// Authorization/PermissionAuthorizationHandler.cs
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using System.Security.Claims;
|
|
|
|
namespace Web.Authorization
|
|
{
|
|
public class PermissionRequirement : IAuthorizationRequirement
|
|
{
|
|
public string Permission { get; }
|
|
|
|
public PermissionRequirement(string permission)
|
|
{
|
|
Permission = permission;
|
|
}
|
|
}
|
|
|
|
public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
|
|
{
|
|
protected override Task HandleRequirementAsync(
|
|
AuthorizationHandlerContext context,
|
|
PermissionRequirement requirement)
|
|
{
|
|
if (context.User == null || !context.User.Identity.IsAuthenticated)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
// Admin role bypasses all permission checks
|
|
if (context.User.IsInRole("Admin"))
|
|
{
|
|
context.Succeed(requirement);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
// Check if user has the required permission claim
|
|
var hasPermission = context.User.Claims
|
|
.Any(c => c.Type == Permissions.ClaimType &&
|
|
c.Value == requirement.Permission);
|
|
|
|
if (hasPermission)
|
|
{
|
|
context.Succeed(requirement);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
|
|
// This provider auto-creates policies for every permission
|
|
public class PermissionPolicyProvider : IAuthorizationPolicyProvider
|
|
{
|
|
private readonly DefaultAuthorizationPolicyProvider _fallbackProvider;
|
|
|
|
public PermissionPolicyProvider(Microsoft.Extensions.Options.IOptions<AuthorizationOptions> options)
|
|
{
|
|
_fallbackProvider = new DefaultAuthorizationPolicyProvider(options);
|
|
}
|
|
|
|
public Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
|
|
{
|
|
// If the policy name matches a known permission, create a policy for it
|
|
var allPermissions = Permissions.GetAll();
|
|
|
|
if (allPermissions.Contains(policyName))
|
|
{
|
|
var policy = new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddRequirements(new PermissionRequirement(policyName))
|
|
.Build();
|
|
|
|
return Task.FromResult<AuthorizationPolicy?>(policy);
|
|
}
|
|
|
|
return _fallbackProvider.GetPolicyAsync(policyName);
|
|
}
|
|
|
|
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
|
|
{
|
|
return _fallbackProvider.GetDefaultPolicyAsync();
|
|
}
|
|
|
|
public Task<AuthorizationPolicy?> GetFallbackPolicyAsync()
|
|
{
|
|
return _fallbackProvider.GetFallbackPolicyAsync();
|
|
}
|
|
}
|
|
} |