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