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>();
上面是系統自帶的策略,可是這種狀況可能比較雞肋。那麼自定義策略使得比較靈活。cookie
自定義 策略,繼承 IAuthorizationRequirement,在 HandleRequirementAsync 實現本身自定義的策略規則,好比下面是實現用戶信息,支持2種用戶郵箱才容許訪問特定頁面或接口等。async
/// <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(); }
用戶登陸 信息ide
[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 = "登陸失敗" }); } }