Search code examples
asp.net-coreauthenticationauthorization

ASP.NET Core 5.0 Customizing Authorization


I implemented an authorization handler to grab the area, controller, and action then validating the user’s access.

public class PermissionsAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
    private readonly ISecurityTrimmingService _securityTrimmingService;

    public PermissionsAuthorizationHandler(ISecurityTrimmingService securityTrimmingService)
    {
        _securityTrimmingService = securityTrimmingService;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
    {
        if (context.Resource is RouteEndpoint endpoint)
        {
            endpoint.RoutePattern.RequiredValues.TryGetValue("controller", out var _controller);
            var controller = _controller.ToString();

            endpoint.RoutePattern.RequiredValues.TryGetValue("action", out var _action);
            var action = _action.ToString();

            endpoint.RoutePattern.RequiredValues.TryGetValue("area", out var _area);
            var area = _area.ToString();

            var isAuthenticated = context.User.Identity.IsAuthenticated;
            if (isAuthenticated && _controller != null && _action != null && _securityTrimmingService.CanCurrentUserAccess(area, controller, action))
            {
                context.Succeed(requirement);
            }
        }
        return Task.CompletedTask;
    }
}

It worked properly in ASP.NET Core 3.1, but there is a problem with version 5.0:

RoutePattern doesn't contain a definition for RequiredValues...


Solution

  • Change the if condition, use HttpContext instead of RouteEndpoint.

    if (context.Resource is HttpContext httpContext)

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DynamicPermissionRequirement requirement)
    {
        if (context.Resource is HttpContext httpContext)
        {
            httpContext.GetRouteData().Values.TryGetValue("controller", out var _controller);
            var controller = _controller.ToString();
    
            httpContext.GetRouteData().Values.TryGetValue("action", out var _action);
            var action = _action.ToString();
    
            httpContext.GetRouteData().Values.TryGetValue("area", out var _area);
            var area = _area.ToString();
    
            var isAuthenticated = context.User.Identity.IsAuthenticated;
    
            if (isAuthenticated && _controller != null && _action != null && _securityTrimmingService.CanCurrentUserAccess(area, controller, action))
            {
                context.Succeed(requirement);
            }
        }
        return Task.CompletedTask;
    }