Visual

18 基于 Claim 和 Policy 的授权 下.mp4 (81.39MB)

一句话的事儿

  • 使用Claims
  • 自定义 Policy
    • RequireAssertion
    • AddRequirements

Policy 内置的方式

  • RequireAuthenticatedUser —>必须是登录用户
  • RequireClaim —>要求特定的Claim出现,并且对应的值也是特定的值
  • RequireRole —>要求是特定的角色
  • RequireUserName —>特定的用户名

Policy 自定义

  • RequireAssertion —>
  • AddRequirements —>

    RequireAssertion

  1. services.AddAuthorization(options =>
  2. {
  3. options.AddPolicy("仅限管理员", policy => policy.RequireRole("Administrators"));
  4. options.AddPolicy("编辑专辑", policy => policy.RequireClaim("Edit Albums"));
  5. options.AddPolicy("编辑专辑1", policy => policy.RequireAssertion(context =>
  6. {
  7. return context.User.HasClaim(c => c.Type == "Edit Albums");
  8. }));
  9. });

AddRequirements

  • IAuthorizationRequirement
    • AuthorizationHandler
    • AuthorizationHandler
    • …(一个 Requirement 可以有多个 Handler)
    • 如果一个 Handler 返回 Succeed,而其他的都没有返回 Fail,那么这个 Requirement 就被满足了

18 基于 Claim 和 Policy 的授权 下 - 图2

EmailRequirement:

  1. using Microsoft.AspNetCore.Authorization;
  2. namespace Heavy.Web.Auth
  3. {
  4. public class EmailRequirement : IAuthorizationRequirement
  5. {
  6. public string RequiredEmail { get; set; }
  7. public EmailRequirement(string requiredEmail)
  8. {
  9. RequiredEmail = requiredEmail;
  10. }
  11. }
  12. }

EmailHandler:

  1. using System.Linq;
  2. using System.Threading.Tasks;
  3. using Microsoft.AspNetCore.Authorization;
  4. namespace Heavy.Web.Auth
  5. {
  6. public class EmailHandler : AuthorizationHandler<EmailRequirement>
  7. {
  8. protected override Task HandleRequirementAsync(
  9. AuthorizationHandlerContext context,
  10. EmailRequirement requirement)
  11. {
  12. var claim = context.User.Claims.FirstOrDefault(c => c.Type == "Email");
  13. if (claim != null && claim.Value.EndsWith(requirement.RequiredEmail))
  14. {
  15. context.Succeed(requirement);
  16. }
  17. return Task.CompletedTask;
  18. }
  19. }
  20. }

配置 Requirement:

  1. services.AddAuthorization(options =>
  2. {
  3. options.AddPolicy("仅限管理员", policy => policy.RequireRole("Administrators"));
  4. options.AddPolicy("编辑专辑", policy => policy.RequireClaim("Edit Albums"));
  5. //options.AddPolicy("编辑专辑1", policy => policy.RequireClaim("Edit Albums", new List<string> { "123", "456", "789" }));
  6. options.AddPolicy("编辑专辑1", policy => policy.RequireAssertion(context =>
  7. {
  8. return context.User.HasClaim(c => c.Type == "Edit Albums");
  9. }));
  10. options.AddPolicy("编辑专辑2", policy => policy.AddRequirements(
  11. new EmailRequirement("@126.com")));
  12. });
  13. // 注册 Handler
  14. services.AddSingleton<IAuthorizationHandler, EmailHandler>();

一个 Policy 里面的多个 Requirement 必须都满足才能通过:

  1. options.AddPolicy("编辑专辑2", policy => policy.AddRequirements(
  2. new EmailRequirement("@126.com"),
  3. new QualifiedUserRequirement()));