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错误,请重新登录")); |
| } |
| |
| |
| |
| |
| |
| |
| public Task ForbidAsync(AuthenticationProperties? properties) |
| { |
| _context.Response.StatusCode = 403; |
| return Task.CompletedTask; |
| } |
此处鉴权给的值是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
| 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; |
| |
| |
| |
| |
| |
| |
| |
| 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错误,请重新登录")); |
| } |
| |
| |
| |
| |
| |
| |
| |
| public Task ChallengeAsync(AuthenticationProperties? properties) |
| { |
| _context.Response.Redirect("/api/Login/NoLogin"); |
| return Task.CompletedTask; |
| } |
| |
| |
| |
| |
| |
| |
| |
| public Task ForbidAsync(AuthenticationProperties? properties) |
| { |
| _context.Response.StatusCode = 403; |
| return Task.CompletedTask; |
| } |
| } |
| |
多授权方案,每个授权策略都需要通过
那么也可以使用多鉴权架构,Cookie可用于web浏览器,token用于终端API调用
改造效果:
多鉴权方案
Program.cs
| |
| #region Cookie |
| builder.Services.AddAuthentication("Cookies").AddCookie(o =>{ |
| o.LoginPath = "/api/Login/NoLogin"; |
| }); |
| |
| #region 自定义Token验证 |
| builder.Services.AddAuthentication(option => |
| { |
| |
| option.AddScheme<TokenAuthenticationHandler>("token", "myToken"); |
| option.DefaultAuthenticateScheme = "token"; |
| option.DefaultChallengeScheme = "token"; |
| option.DefaultForbidScheme = "token"; |
| }); |
| #endregion |
| #endregion |
| |
| |
| #region 授权 |
| |
| |
| |
| |
| |
| builder.Services.AddAuthorization(option => |
| { |
| option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1"))); |
| |
| }); |
| #endregion |
TestController.cs
| [ApiController] |
| [Route("api/[controller]")] |
| public class TestController : ControllerBase |
| { |
| [Authorize(Policy = "MyPolicy",AuthenticationSchemes = $"token,Cookies")] |
| [HttpGet] |
| public async Task<string> Get() |
| { |
| return await Task.FromResult(DateTime.Now.ToString()); |
| } |
| } |
授权绑定鉴权
| |
| #region Cookie |
| builder.Services.AddAuthentication("Cookies").AddCookie(o =>{ |
| o.LoginPath = "/api/Login/NoLogin"; |
| }); |
| |
| #region 自定义Token验证 |
| builder.Services.AddAuthentication(option => |
| { |
| |
| option.AddScheme<TokenAuthenticationHandler>("token", "myToken"); |
| |
| option.DefaultChallengeScheme = "token"; |
| option.DefaultForbidScheme = "token"; |
| }); |
| #endregion |
| #endregion |
| builder.Services.AddAuthorization(option => |
| { |
| option.AddPolicy("MyPolicy",p =>p.AddAuthenticationSchemes("token").Requirements.Add(new MyAuthorizationHandler("1"))); |
| option.AddPolicy("MyPolicy1", p =>p.AddAuthenticationSchemes("Cookies").Requirements.Add(new MyAuthorizationHandler1("admin"))); |
| }); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?