fix security
This commit is contained in:
@@ -1,19 +1,57 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
|
||||
{
|
||||
private readonly ILogger<PermissionAuthorizationHandler> _logger;
|
||||
private readonly IHttpContextAccessor _http;
|
||||
private readonly ClinicalMetrics _metrics;
|
||||
|
||||
public PermissionAuthorizationHandler(
|
||||
ILogger<PermissionAuthorizationHandler> logger,
|
||||
IHttpContextAccessor http,
|
||||
ClinicalMetrics metrics)
|
||||
{
|
||||
_logger = logger;
|
||||
_http = http;
|
||||
_metrics = metrics;
|
||||
}
|
||||
|
||||
protected override Task HandleRequirementAsync(
|
||||
AuthorizationHandlerContext context,
|
||||
PermissionRequirement requirement)
|
||||
{
|
||||
var roleClaim = context.User.FindFirst("clinical_role")?.Value;
|
||||
if (roleClaim is null)
|
||||
{
|
||||
LogAuthorizationFailure(context.User, "none", requirement.Permission);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var role = ClinicalRoleExtensions.FromDbString(roleClaim);
|
||||
if (ClinicalRolePermissionMap.HasPermission(role, requirement.Permission))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAuthorizationFailure(context.User, roleClaim, requirement.Permission);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void LogAuthorizationFailure(ClaimsPrincipal user, string role, string permission)
|
||||
{
|
||||
var username = user.FindFirst(ClaimTypes.Name)?.Value ?? "unknown";
|
||||
var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "unknown";
|
||||
var endpoint = _http.HttpContext?.GetEndpoint()?.DisplayName ?? "unknown";
|
||||
|
||||
_logger.LogWarning(
|
||||
"Authorization denied: user={User} (id={UserId}), role={Role}, " +
|
||||
"requiredPermission={Permission}, endpoint={Endpoint}",
|
||||
username, userId, role, permission, endpoint);
|
||||
|
||||
_metrics.AuthorizationFailuresTotal.WithLabels(permission, role).Inc();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user