Query Database for Role Authorization Before Each Action in ASP.NET Core

ASP.NET Core combined with Identity already provide a simple way to check roles once after login, but I would like to query the database for the current roles for the current user before every controller action.

I've read up on Role-based, Policy-based, and Claims-based authorization from Microsoft. (https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction) None of these solutions seem to check roles on every action. Here is my latest attempt to implement the desired outcome, in the form of some policy-based authorization:

In Startup.cs:

DatabaseContext context = new DatabaseContext();

services.AddAuthorization(options =>
{
    options.AddPolicy("IsManager",
        policy => policy.Requirements.Add(new IsManagerRequirement(context)));
    options.AddPolicy("IsAdmin",
        policy => policy.Requirements.Add(new IsAdminRequirement(context)));
});

In my requirements file:

public class IsAdminRequirement : IAuthorizationRequirement
{
    public IsAdminRequirement(DatabaseContext context)
    {
        _context = context;
    }

    public DatabaseContext _context { get; set; }
}
public class IsAdminHandler : AuthorizationHandler<IsAdminRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsAdminRequirement requirement)
    {
        // Enumerate all current users roles
        int userId = Int32.Parse(context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value);
        Roles adminRoles = requirement._context.Roles.FirstOrDefault(r => r.Name == "Administrator" && r.IsActive == true);
        bool hasRole = requirement._context.UserRoles.Any(ur => ur.UserId == userId && adminRoles.Id == ur.RoleId && ur.IsActive == true);
        // Check for the correct role
        if (hasRole)
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

and in the controller:

[HttpGet]
[Authorize(Policy = "IsAdmin")]
public async Task<IActionResult> Location()
{
    // do action here
}

With this code, the requirement middleware is somehow never called, and therefore the database is never checked.

How would I correctly query the database to check for the current user's roles before carrying out each controller action?

链接地址: http://www.djcxy.com/p/90188.html

上一篇: .Net Core 1.1中基于角色的身份验证

下一篇: 查询数据库以获取ASP.NET Core中的每个操作之前的角色授权