ASP.NET Core 鉴权授权三(添加自定义授权策略)

  • ASP.NET Core 鉴权授权三(添加自定义授权策略)已关闭评论
  • 103 次浏览
  • A+
所属分类:.NET技术
摘要

此处鉴权给的值是6,授权用的1,尝试访问
基于策略的授权中有一个很重要的概念是Requirements,每一个Requirement都代表一个授权条件。
Requirement需要继承接口IAuthorizationRequirement。


Program.cs

#region 授权 builder.Services.AddAuthorization(option => {     //添加自定义授权策略     option.AddPolicy("MyPolicy",p => p.RequireClaim(ClaimTypes.NameIdentifier,"1")); }); #endregion 

TestController.cs 应用自定义授权策略

[ApiController] [Route("api/[controller]")] public class TestController : ControllerBase {     [Authorize("MyPolicy")]     [HttpGet]     public async Task<string> Get()     {         return await Task.FromResult(DateTime.Now.ToString());     } } 

TokenAuthenticationHandler.cs

    public Task<AuthenticateResult> AuthenticateAsync()     {         string token = _context.Request.Headers["Authorization"];         if (token == "test")         {             ClaimsIdentity identity = new ClaimsIdentity("Ctm");             identity.AddClaims(new List<Claim>(){                 new Claim(ClaimTypes.Name,"admin"),                 new Claim(ClaimTypes.NameIdentifier,"6")             });             var claimsPrincipal = new ClaimsPrincipal(identity);             return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));         }         return Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));     }     /// <summary>     /// 没有权限访问     /// </summary>     /// <param name="properties"></param>     /// <returns></returns>     /// <exception cref="NotImplementedException"></exception>     public Task ForbidAsync(AuthenticationProperties? properties)     {         _context.Response.StatusCode = 403;         return Task.CompletedTask;     } 

此处鉴权给的值是6,授权用的1,尝试访问
ASP.NET Core 鉴权授权三(添加自定义授权策略)

重要概念

基于策略的授权中有一个很重要的概念是Requirements,每一个Requirement都代表一个授权条件。
Requirement需要继承接口IAuthorizationRequirement。

已经内置了一些常用的实现:
AssertionRequirement :使用最原始的断言形式来声明授权策略。

DenyAnonymousAuthorizationRequirement :用于表示禁止匿名用户访问的授权策略,并在AuthorizationOptions中将其设置为默认策略。

ClaimsAuthorizationRequirement :用于表示判断Cliams中是否包含预期的Claims的授权策略。

RolesAuthorizationRequirement :用于表示使用ClaimsPrincipal.IsInRole来判断是否包含预期的Role的授权策略。

NameAuthorizationRequirement:用于表示使用ClaimsPrincipal.Identities.Name来判断是否包含预期的Name的授权策略。

OperationAuthorizationRequirement:用于表示基于操作的授权策略。

当内置的Requirement不能满足需求时,可以定义自己的Requirement.

自定义Requirement

builder.Services.AddAuthorization(option => {     option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1"))); }); 

MyAuthorizationHandler.cs

public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationHandler>, IAuthorizationRequirement {     private readonly string _userId;     public MyAuthorizationHandler(string userId)     {         _userId = userId;     }     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler requirement)     {         if (context.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)         && context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == _userId)         {             context.Succeed(requirement);         }         else         {             context.Fail();         }         return Task.CompletedTask;     } } 

多授权方案

builder.Services.AddAuthorization(option => {     option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));     option.AddPolicy("MyPolicy1", p => p.Requirements.Add(new MyAuthorizationHandler1("admin"))); }); 

MyAuthorizationHandler1.cs

public class MyAuthorizationHandler1 : AuthorizationHandler<MyAuthorizationHandler1>, IAuthorizationRequirement {     private readonly string _userName;     public MyAuthorizationHandler1(string userName)     {         _userName = userName;     }     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler1 requirement)     {         if (context.User.HasClaim(c => c.Type == ClaimTypes.Name)         && context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Name)).Value == _userName)         {             context.Succeed(requirement);         }         else         {             context.Fail();         }         return Task.CompletedTask;     } } 

TestController.cs

[ApiController] [Route("api/[controller]")] public class TestController : ControllerBase {     [Authorize(Policy = "MyPolicy")]     [Authorize(Policy = "MyPolicy1")]     [HttpGet]     public async Task<string> Get()     {         return await Task.FromResult(DateTime.Now.ToString());     } } 

鉴权方案 TokenAuthenticationHandler.cs

public class TokenAuthenticationHandler : IAuthenticationHandler {     private AuthenticationScheme _scheme;     private HttpContext _context;     /// <summary>     /// 鉴权初始化     /// </summary>     /// <param name="scheme">鉴权架构名称</param>     /// <param name="context">HttpContext</param>     /// <returns></returns>     /// <exception cref="NotImplementedException"></exception>     public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)     {         _scheme = scheme;         _context = context;         return Task.CompletedTask;     }     public Task<AuthenticateResult> AuthenticateAsync()     {         string token = _context.Request.Headers["Authorization"];         if (token == "test")         {             ClaimsIdentity identity = new ClaimsIdentity("Ctm");             identity.AddClaims(new List<Claim>(){                 new Claim(ClaimTypes.Name,"admin"),                 new Claim(ClaimTypes.NameIdentifier,"1")             });             var claimsPrincipal = new ClaimsPrincipal(identity);             return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));         }         return Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));     }      /// <summary>     /// 未登录     /// </summary>     /// <param name="properties"></param>     /// <returns></returns>     /// <exception cref="NotImplementedException"></exception>     public Task ChallengeAsync(AuthenticationProperties? properties)     {         _context.Response.Redirect("/api/Login/NoLogin");         return Task.CompletedTask;     }      /// <summary>     /// 没有权限访问     /// </summary>     /// <param name="properties"></param>     /// <returns></returns>     /// <exception cref="NotImplementedException"></exception>     public Task ForbidAsync(AuthenticationProperties? properties)     {         _context.Response.StatusCode = 403;         return Task.CompletedTask;     } }  
多授权方案,每个授权策略都需要通过