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>();
上面是系统自带的策略,但是这种情况可能比较c#教程鸡肋。那么自定义策略使得比较灵活。
自定义 策略,继承 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;
}
}
1
登录过后,会根据用户信息对比策略中信息。
[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 = "登录失败"
});
}
}