SurveyVista/Web/Authorization/PermissionAuthorizationHandler.cs
2026-03-07 02:37:33 +01:00

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();
}
}
}