您的位置:首页 > 编程语言 > ASP

ASP.NET CORE[练习10]-Identity-自定义Policy

2019-09-04 17:20 591 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_25991955/article/details/100540155

练习+博客,量化自己的进步!

 

之前的角色校验、Claim校验都是基于Policy的,也可以自定义Policy,更灵活些,更全面些,或者将之前的用户校验、Claim校验合并到自定义的Policy中。

 

policy的内置方法有:

RequireClaim   必须的Claim

RequireRole     必须的角色

RequireUserName  必须的用户名

自定已policy的话,有两个关键的东西:

Requriement、Handle

一个Policy可以有多个Requirement,一个Requriement可以有多个Handler。

自定义Policy就是自定义Requirement,Requriement下面有多个自定义的Handler。

自定义Requiredment:IAuthorizationRequirement

自定义Handler:AuthorizationHandler<自定义Requiredment>

 

案例:

自定义Policy,身份是Administrator 或 Claim是EditeStudent 或 账号必须是s开头才能访问Student学生管理。

1.自定义Requirement、Requirehanlder

自定义Requriement:

[code]public class DefinedRequirement:IAuthorizationRequirement
{
}

自定义Handler:
 

[code]public class AdministratorRoleHandler : AuthorizationHandler<DefinedRequirement>
{
// 实现抽象方法,如果角色为Administrator,DefinedRequrirement就通过校验
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DefinedRequirement requirement)
{
// context可以获取登录信息
if (context.User.IsInRole("Administrator"))
{
// requirement就这么写就行了。
context.Succeed(requirement);
}
// 方法返回类型为Task
return Task.CompletedTask;
}
}
[code]public class ClaimsHandler : AuthorizationHandler<DefinedRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DefinedRequirement requirement)
{
// 如果用户拥有EditeStudent Claim,就通过校验
if (context.User.HasClaim(x => x.Type == "EditStudent"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
[code]public class UserNameHandler : AuthorizationHandler<DefinedRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DefinedRequirement requirement)
{
// 如果用户账号以字母“s”开头则通过验证
if (context.User.Identity.Name.StartsWith("z"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}

2.注入服务

[code]services.AddAuthorization(options =>
{
// Admin是这条授权策略的名字,第二个参数是具体策略,RequireRole的参数类型是params string[]
//options.AddPolicy("Admin", policy => policy.RequireRole("Administrator"));
// 写法同Role差不多相同
//options.AddPolicy("Student", policy => policy.RequireClaim("EditStudent"));
// 添加Requirement,这个参数类型是params,可以添加多个Requriement
options.AddPolicy("Defined", policy => policy.AddRequirements(new DefinedRequirement()));

});
services.AddSingleton<IAuthorizationHandler, AdministratorRoleHandler>();
services.AddSingleton<IAuthorizationHandler, ClaimsHandler>();
services.AddSingleton<IAuthorizationHandler, UserNameHandler>();

*注意下面上个Singletion,自定义的Handler也要注入到service中。

 

3.应用

[code][Authorize(Policy = "Defined")]
public class StudentController : Controller
{
...

应用与之前的policy都一样。

 

测试效果:

又添加了一个猪八戒用户,之前的孙悟空身份即绑定了角色Administrator,又是字母“s”开头,Claim也配置了EditStudent,因此,添加了一个什么都没配置的猪八戒用户。

登录猪八戒用户后,访问Student自动跳转到/Account/AccessDenied,这个路径是.NET CORE Identity默认的异常路径,只需要添加一个自定义的视图即可。

然后,我们将首字母改为“z”

因为三个RequrireHandler是或的关系,因此只需要满足首字母为“z”这个一个Handler的校验就可以通过了。

 

扩展:

那如何让三个Handler为并关系呢,即为必须同时都满足条件,才能访问?

这么些就可以了。

 

3ff8
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: