如何制作一个可以调用数据库以检查用户声明以授权用户的中间件,在ASP.NET Core 2.2中

时间:2019-05-27 06:12:48

标签: c# jwt asp.net-core-2.2 claims ef-core-2.2

在asp.net core 2.2中制作中间件的最佳实践是什么或实现中间件的正确方法是什么。

我的场景是 我在asp.net core 2.2中构建了一个Web API,并且在控制器中实现了授权,例如[Authorize(Policy = "UserDelete")] UserDelete这样的用户声明我的问题是我有很多用户声明用户可以拥有更多或更多少于20个声明,如果我将此声明保存在JWT中,可能会导致JWT很大,我要做的就是调用声明或创建一个中间件来为此声明调用数据库,这样我需要保存在JWT中的就是用户证书。

1 个答案:

答案 0 :(得分:0)

您需要做的就是创建一个AuthorizationHandler,请按照说明进行操作: 1-创建一个类并将其命名为MinimumPermissionHandler或其他名称。在其中复制并粘贴以下代码:

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-定义一个策略并将处理程序添加到服务,因此将以下几行添加到您的Startup类中:

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-最后,要检查访问权限,只需将此代码放在Controller上方

[Authorize(Policy = "AccessControl")]