How to make a middleware that can call database to check user claims to authorize a user in asp.net core 2.2

会有一股神秘感。 提交于 2021-01-29 05:30:58

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!