翼度科技»论坛 编程开发 .net 查看内容

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

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
Program.cs
  1. #region 授权
  2. builder.Services.AddAuthorization(option =>
  3. {
  4.     //添加自定义授权策略
  5.     option.AddPolicy("MyPolicy",p => p.RequireClaim(ClaimTypes.NameIdentifier,"1"));
  6. });
  7. #endregion
复制代码
TestController.cs 应用自定义授权策略
  1. [ApiController]
  2. [Route("api/[controller]")]
  3. public class TestController : ControllerBase
  4. {
  5.     [Authorize("MyPolicy")]
  6.     [HttpGet]
  7.     public async Task<string> Get()
  8.     {
  9.         return await Task.FromResult(DateTime.Now.ToString());
  10.     }
  11. }
复制代码
TokenAuthenticationHandler.cs
  1.     public Task<AuthenticateResult> AuthenticateAsync()
  2.     {
  3.         string token = _context.Request.Headers["Authorization"];
  4.         if (token == "test")
  5.         {
  6.             ClaimsIdentity identity = new ClaimsIdentity("Ctm");
  7.             identity.AddClaims(new List<Claim>(){
  8.                 new Claim(ClaimTypes.Name,"admin"),
  9.                 new Claim(ClaimTypes.NameIdentifier,"6")
  10.             });
  11.             var claimsPrincipal = new ClaimsPrincipal(identity);
  12.             return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));
  13.         }
  14.         return Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));
  15.     }
  16.     /// <summary>
  17.     /// 没有权限访问
  18.     /// </summary>
  19.     /// <param name="properties"></param>
  20.     /// <returns></returns>
  21.     /// <exception cref="NotImplementedException"></exception>
  22.     public Task ForbidAsync(AuthenticationProperties? properties)
  23.     {
  24.         _context.Response.StatusCode = 403;
  25.         return Task.CompletedTask;
  26.     }
复制代码
此处鉴权给的值是6,授权用的1,尝试访问

重要概念

基于策略的授权中有一个很重要的概念是Requirements,每一个Requirement都代表一个授权条件。
Requirement需要继承接口IAuthorizationRequirement。
已经内置了一些常用的实现:
AssertionRequirement :使用最原始的断言形式来声明授权策略。
DenyAnonymousAuthorizationRequirement :用于表示禁止匿名用户访问的授权策略,并在AuthorizationOptions中将其设置为默认策略。
ClaimsAuthorizationRequirement :用于表示判断Cliams中是否包含预期的Claims的授权策略。
RolesAuthorizationRequirement :用于表示使用ClaimsPrincipal.IsInRole来判断是否包含预期的Role的授权策略。
NameAuthorizationRequirement:用于表示使用ClaimsPrincipal.Identities.Name来判断是否包含预期的Name的授权策略。
OperationAuthorizationRequirement:用于表示基于操作的授权策略。
当内置的Requirement不能满足需求时,可以定义自己的Requirement.
自定义Requirement
  1. builder.Services.AddAuthorization(option =>
  2. {
  3.     option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
  4. });
复制代码
MyAuthorizationHandler.cs
  1. public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationHandler>, IAuthorizationRequirement
  2. {
  3.     private readonly string _userId;
  4.     public MyAuthorizationHandler(string userId)
  5.     {
  6.         _userId = userId;
  7.     }
  8.     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler requirement)
  9.     {
  10.         if (context.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)
  11.         && context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == _userId)
  12.         {
  13.             context.Succeed(requirement);
  14.         }
  15.         else
  16.         {
  17.             context.Fail();
  18.         }
  19.         return Task.CompletedTask;
  20.     }
  21. }
复制代码
多授权方案
  1. builder.Services.AddAuthorization(option =>
  2. {
  3.     option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
  4.     option.AddPolicy("MyPolicy1", p => p.Requirements.Add(new MyAuthorizationHandler1("admin")));
  5. });
复制代码
MyAuthorizationHandler1.cs
  1. public class MyAuthorizationHandler1 : AuthorizationHandler<MyAuthorizationHandler1>, IAuthorizationRequirement
  2. {
  3.     private readonly string _userName;
  4.     public MyAuthorizationHandler1(string userName)
  5.     {
  6.         _userName = userName;
  7.     }
  8.     protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler1 requirement)
  9.     {
  10.         if (context.User.HasClaim(c => c.Type == ClaimTypes.Name)
  11.         && context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Name)).Value == _userName)
  12.         {
  13.             context.Succeed(requirement);
  14.         }
  15.         else
  16.         {
  17.             context.Fail();
  18.         }
  19.         return Task.CompletedTask;
  20.     }
  21. }
复制代码
TestController.cs
  1. [ApiController]
  2. [Route("api/[controller]")]
  3. public class TestController : ControllerBase
  4. {
  5.     [Authorize(Policy = "MyPolicy")]
  6.     [Authorize(Policy = "MyPolicy1")]
  7.     [HttpGet]
  8.     public async Task<string> Get()
  9.     {
  10.         return await Task.FromResult(DateTime.Now.ToString());
  11.     }
  12. }
复制代码
鉴权方案 TokenAuthenticationHandler.cs
  1. public class TokenAuthenticationHandler : IAuthenticationHandler
  2. {
  3.     private AuthenticationScheme _scheme;
  4.     private HttpContext _context;
  5.     /// <summary>
  6.     /// 鉴权初始化
  7.     /// </summary>
  8.     /// <param name="scheme">鉴权架构名称</param>
  9.     /// <param name="context">HttpContext</param>
  10.     /// <returns></returns>
  11.     /// <exception cref="NotImplementedException"></exception>
  12.     public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
  13.     {
  14.         _scheme = scheme;
  15.         _context = context;
  16.         return Task.CompletedTask;
  17.     }
  18.     public Task<AuthenticateResult> AuthenticateAsync()
  19.     {
  20.         string token = _context.Request.Headers["Authorization"];
  21.         if (token == "test")
  22.         {
  23.             ClaimsIdentity identity = new ClaimsIdentity("Ctm");
  24.             identity.AddClaims(new List<Claim>(){
  25.                 new Claim(ClaimTypes.Name,"admin"),
  26.                 new Claim(ClaimTypes.NameIdentifier,"1")
  27.             });
  28.             var claimsPrincipal = new ClaimsPrincipal(identity);
  29.             return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));
  30.         }
  31.         return Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));
  32.     }
  33.     /// <summary>
  34.     /// 未登录
  35.     /// </summary>
  36.     /// <param name="properties"></param>
  37.     /// <returns></returns>
  38.     /// <exception cref="NotImplementedException"></exception>
  39.     public Task ChallengeAsync(AuthenticationProperties? properties)
  40.     {
  41.         _context.Response.Redirect("/api/Login/NoLogin");
  42.         return Task.CompletedTask;
  43.     }
  44.     /// <summary>
  45.     /// 没有权限访问
  46.     /// </summary>
  47.     /// <param name="properties"></param>
  48.     /// <returns></returns>
  49.     /// <exception cref="NotImplementedException"></exception>
  50.     public Task ForbidAsync(AuthenticationProperties? properties)
  51.     {
  52.         _context.Response.StatusCode = 403;
  53.         return Task.CompletedTask;
  54.     }
  55. }
复制代码
多授权方案,每个授权策略都需要通过


来源:https://www.cnblogs.com/leafroc/Undeclared/17941091
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具