问题
What is the best practice to make a middleware or a proper way to implement middleware in asp.net core 2.2.
My Scenario is
I have a web api build in asp.net core 2.2 and I implement authorization in my controller something like this [Authorize(Policy = "UserDelete")]
UserDelete
is a user claim my problem is i have many user claim can user have, more or less up to 20 claims if I save this claims in JWT it can cause large size of JWT all i want to do is to call claims or create a middleware that call the database for this claims so that all i need to save in JWT is user credentials.
回答1:
All you need is to create an AuthorizationHandler, please follow the instructions:
1- create a class and name it MinimumPermissionHandler
or whatever. copy and paste following codes in it:
public class MinimumPermissionRequirement : IAuthorizationRequirement { }
public class MinimumPermissionHandler : AuthorizationHandler<MinimumPermissionRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumPermissionRequirement requirement)
{
if (!(context.Resource is AuthorizationFilterContext filterContext))
{
context.Fail();
return Task.CompletedTask;
}
//check if token has subjectId
var subClaim = context.User?.Claims?.FirstOrDefault(c => c.Type == "sub");
if (subClaim == null)
{
context.Fail();
return Task.CompletedTask;
}
//check if token is expired
var exp = context.User.Claims.FirstOrDefault(c => c.Type == "exp")?.Value;
if(exp == null || new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(long.Parse(exp)).ToLocalTime() < DateTime.Now)
{
context.Fail();
return Task.CompletedTask;
}
//other checkpoints
//your db functions to check if user has desired claims
context.Succeed(requirement);
return Task.CompletedTask;
}
}
2- Define a policy and add the handler to services, so put this lines in your Startup class:
public void ConfigureServices(IServiceCollection services)
{
//deleted extra lines for brevity
services.AddAuthorization(options =>
{
options.AddPolicy("AccessControl", policy =>
{
policy.RequireAuthenticatedUser();
policy.AddRequirements(new MinimumPermissionRequirement());
});
});
//injection
services.AddScoped<IAuthorizationHandler, MinimumPermissionHandler>();
}
3- Finally for checking access permission just put this code above Controllers
[Authorize(Policy = "AccessControl")]
来源:https://stackoverflow.com/questions/56320523/how-to-make-a-middleware-that-can-call-database-to-check-user-claims-to-authoriz