ASP.NET Core 5.0自定义授权

ASP.NET Core 5.0 Customizing Authorization

我实现了一个授权处理程序来获取 areacontrolleraction,然后验证用户的访问权限。

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

它在 ASP.NET Core 3.1 中工作正常,但是 5.0 版本有问题:

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

更改if条件,使用HttpContext代替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;
}