ASP.NET Core 6.0 添加 JWT 认证和授权( 四 )

运行 HandleRequirementAsync 时,会将用户的 Claim 中 ClaimType 为 Permission 的项取出,并获取其 Value 组成一个 List<string> 。
接着验证 Requirement 是否满足授权,满足则运行 context.Succeed  。
6 添加授权处理程序在 Program.cs 中,将 PermissionAuthorizationHandler 添加到 DI 中:
builder.Services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();7 添加授权策略builder.Services.AddAuthorization(options =>{options.AddPolicy(UserPermission.UserCreate, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(UserPermission.UserCreate)));options.AddPolicy(UserPermission.UserUpdate, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(UserPermission.UserUpdate)));options.AddPolicy(UserPermission.UserDelete, policy => policy.AddRequirements(new PermissionAuthorizationRequirement(UserPermission.UserDelete)));});8 控制器配置【ASP.NET Core 6.0 添加 JWT 认证和授权】控制器如下:
[Route("api/[controller]/[action]")][ApiController]public class UserController : ControllerBase{[HttpGet][Authorize(UserPermission.UserCreate)]public ActionResult<string> UserCreate() => "UserCreate";[HttpGet][Authorize(UserPermission.UserUpdate)]public ActionResult<string> UserUpdate() => "UserUpdate";[HttpGet][Authorize(UserPermission.UserDelete)]public ActionResult<string> UserDelete() => "UserDelete";}基于上面的假定,用户访问接口的情况如下:
/api/User/UserCreate #成功/api/User/UserUpdate #成功/api/User/UserDelete #403无权限至此,基于策略(Policy)的授权其实已经基本完成 。
接下去的内容,将是对上面一些内容的完善或补充 。
完善:实现策略提供程序 PolicyProvider一般添加授权策略如下是在 Program.cs 中,方式如下:
builder.Services.AddAuthorization(options =>{options.AddPolicy("policy", policy => policy.RequireClaim("EmployeeNumber"));});通过 AuthorizationOptions.AddPolicy 添加授权策略这种方式不灵活,无法动态添加 。
通过实现 IAuthorizationPolicyProvider 并添加到 DI 中,可以实现动态添加 Policy 。
IAuthorizationPolicyProvider 的默认实现为 DefaultAuthorizationPolicyProvider  。
实现一个 PolicyProvider 如下:
public class TestAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider, IAuthorizationPolicyProvider{public Test2AuthorizationPolicyProvider(IOptions<AuthorizationOptions> options) : base(options) {}public new Task<AuthorizationPolicy> GetDefaultPolicyAsync()=> return base.GetDefaultPolicyAsync();public new Task<AuthorizationPolicy?> GetFallbackPolicyAsync()return base.GetFallbackPolicyAsync();public new Task<AuthorizationPolicy?> GetPolicyAsync(string policyName){if (policyName.StartsWith(UserPermission.User)){var policy = new AuthorizationPolicyBuilder("Bearer");policy.AddRequirements(new PermissionAuthorizationRequirement(policyName));return Task.FromResult<AuthorizationPolicy?>(policy.Build());}return base.GetPolicyAsync(policyName);}}注意:自定义的 TestAuthorizationPolicyProvider 必须实现 IAuthorizationPolicyProvider,否则添加到 DI 时会不生效 。
在 Program.cs 中,将自定义的 PolicyProvider 添加到 DI 中:
builder.Services.AddSingleton<IAuthorizationPolicyProvider, TestAuthorizationPolicyProvider>();注意:只会生效最后一个添加的 PolicyProvider 。
补充:自定义 AuthorizationMiddleware自定义 AuthorizationMiddleware 可以:

  • 返回自定义的响应
  • 增强(或者说改变)默认的 challenge 或 forbid 响应
具体请查看官方文档自定义 AuthorizationMiddleware 的行为
补充:MiniApi 的授权在 MiniApi 中几乎都是形如 MapGet() 的分支节点,这类终结点无法使用 [Authorize] 标签,可以用使用 RequireAuthorization("Something") 进行授权,如:
app.MapGet("/helloworld", () => "Hello World!").RequireAuthorization("AtLeast21");作者:芦荟柚子茶
链接:
https://www.cnblogs.com/clis/p/16151872.html




推荐阅读