services.AddAuthorization(options => { options.AddPolicy("AdminPolicy", policyBuilder => policyBuilder .RequireRole("Admin")//Claim的Role是Admin .RequireUserName("Eleven")//Claim的Name是Eleven .RequireClaim(ClaimTypes.Email)//必须有某个Cliam //.Combine(qqEmailPolicy) );//内置 options.AddPolicy("UserPolicy", policyBuilder => policyBuilder.RequireAssertion(context => context.User.HasClaim(c => c.Type == ClaimTypes.Role) && context.User.Claims.First(c => c.Type.Equals(ClaimTypes.Role)).Value == "Admin") //.Combine(qqEmailPolicy) );//自定义 //policy层面 没有Requirements //options.AddPolicy("QQEmail", policyBuilder => policyBuilder.Requirements.Add(new QQEmailRequirement())); options.AddPolicy("DoubleEmail", policyBuilder => policyBuilder.Requirements.Add(new DoubleEmailRequirement())); }); services.AddSingleton<IAuthorizationHandler, ZhaoxiMailHandler>(); services.AddSingleton<IAuthorizationHandler, QQMailHandler>();
上面是系统自带的策略,但是这种情况可能比较鸡肋。那么自定义策略使得比较灵活。
自定义 策略,继承 IAuthorizationRequirement,在 HandleRequirementAsync 实现自己自定义的策略规则,比如下面是实现用户信息,支持2种用户邮箱才允许访问特定页面或接口等。
/// <summary> /// 两种邮箱都能支持 /// /// </summary> public class DoubleEmailRequirement : IAuthorizationRequirement { } public class QQMailHandler : AuthorizationHandler<DoubleEmailRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DoubleEmailRequirement requirement) { if (context.User != null && context.User.HasClaim(c => c.Type == ClaimTypes.Email)) { var email = context.User.FindFirst(c => c.Type == ClaimTypes.Email).Value; if (email.EndsWith("@qq.com", StringComparison.OrdinalIgnoreCase)) { context.Succeed(requirement); } else { //context.Fail();//不设置失败 } } return Task.CompletedTask; } } public class ZhaoxiMailHandler : AuthorizationHandler<DoubleEmailRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DoubleEmailRequirement requirement) { if (context.User != null && context.User.HasClaim(c => c.Type == ClaimTypes.Email)) { var email = context.User.FindFirst(c => c.Type == ClaimTypes.Email).Value; if (email.EndsWith("@ZhaoxiEdu.Net", StringComparison.OrdinalIgnoreCase)) { context.Succeed(requirement); } else { //context.Fail(); } } return Task.CompletedTask; } }
登录过后,会根据用户信息对比策略中信息。
[Authorize(AuthenticationSchemes = "Cookies", Policy = "AdminPolicy")] public IActionResult InfoAdminPolicy() { return View(); } [Authorize(AuthenticationSchemes = "Cookies", Policy = "UserPolicy")] public IActionResult InfoUserPolicy() { return View(); } [Authorize(AuthenticationSchemes = "Cookies", Policy = "QQEmail")] public IActionResult InfoQQEmail() { return View(); } [Authorize(AuthenticationSchemes = "Cookies", Policy = "DoubleEmail")] public IActionResult InfoDoubleEmail() { return View(); }
用户登录 信息
[AllowAnonymous] public async Task<IActionResult> LoginCustomScheme(string name, string password) { //base.HttpContext.RequestServices. //IAuthenticationService if ("ElevenCustomScheme".Equals(name, StringComparison.CurrentCultureIgnoreCase) && password.Equals("123456")) { var claimIdentity = new ClaimsIdentity("Custom"); claimIdentity.AddClaim(new Claim(ClaimTypes.Name, name)); claimIdentity.AddClaim(new Claim(ClaimTypes.Email, "xuyang@ZhaoxiEdu.Net")); await base.HttpContext.SignInAsync("CustomScheme", new ClaimsPrincipal(claimIdentity), new AuthenticationProperties { ExpiresUtc = DateTime.UtcNow.AddMinutes(30), });//登录为默认的scheme cookies return new JsonResult(new { Result = true, Message = "登录成功" }); } else { await Task.CompletedTask; return new JsonResult(new { Result = false, Message = "登录失败" }); } }