ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Authentication and authorization (three)

2020-08-16 13:00:40  阅读:279  来源: 互联网

标签:Claim Country three Authentication var new policyBuilder ClaimTypes authorizatio


前言

在写三上是在一的基础上写的,所以有没有看过二是没得关系的,在一中介绍了认证与授权,但是没有去介绍拿到证书后怎样去验证授权。
概念性东西:在这套机制中,把这个权限认证呢,称作为policy。这个policy是怎么样的过程呢?
就像我前面说的,证书也认证了,policy做的是检查你的证书中是否符合我心中的标准。
比如说,我有一个接口实行的是驾驶证检查。结果你只有一张学生证,你不能那一张学生证当驾驶证去开车吧,肯定就不让你访问啊。
也许还有点迷糊,请看正文。正文皆为个人理解,如有错误,请指正。

正文

请看下面的:

services.AddAuthorization(config=> {
	var defaultAuthBuilder = new AuthorizationPolicyBuilder();
	var defaultPolicy = defaultAuthBuilder.RequireAuthenticatedUser().Build();
	config.DefaultPolicy = defaultPolicy;
});

这时候就是在配置授权了。
defaultAuthBuilder.RequireAuthenticatedUser().Build() 中,RequireAuthenticatedUser去要求用户必须经过认证的,也就是不允许匿名用户,这个很好理解。
设置默认的策略认证就是这个了。
这时候我访问:
https://localhost:44350/Home/Secret
是正常的,因为我本来就是认证过的。
然后我改了一下:

services.AddAuthorization(config=> {
	var defaultAuthBuilder = new AuthorizationPolicyBuilder();
	var defaultPolicy = defaultAuthBuilder.RequireAuthenticatedUser().RequireClaim(ClaimTypes.Country).Build();
	config.DefaultPolicy = defaultPolicy;
});

和上面不同的,我加了RequireClaim(ClaimTypes.Country),我要求起码有一个证书你要有国家。

我再次贴下证书的代码,在.net core 认证与授权(一)中也有。

var SchoolClaims = new List<Claim>()
{
	new Claim(ClaimTypes.Name,"Jack"),
	new Claim(ClaimTypes.Email,"Jack@fmail.com")
};

var LicensClaims = new List<Claim>()
{
	new Claim(ClaimTypes.Name,"Jack.li"),
	new Claim(ClaimTypes.Email,"Jack@fmail.com"),
	new Claim("begin","2000.10.1")
};
var SchoolIdentity = new ClaimsIdentity(SchoolClaims,"Student Identity");
var CarManagerIdentity = new ClaimsIdentity(LicensClaims, "Licens Identity");
var userPrincipal = new ClaimsPrincipal(new[] { SchoolIdentity, CarManagerIdentity });

HttpContext.SignInAsync("CookieAuth", userPrincipal);
return RedirectToAction("Index");

在两个证书中,都没得国家。
然后访问:
https://localhost:44350/Home/Secret
img
自动跳转到了一个授权没有通过的网站,恰巧我没有写这个网页,姑且着就是没有通过的意思。
然后我再一个证书中添加了一个:

new Claim(ClaimTypes.Country,"china")

这样我又成功了。
好的,这是默认的策略,那么如何自定义呢?

config.AddPolicy("Claim.Country", policyBuilder =>
{
	policyBuilder.RequireClaim(ClaimTypes.Country);
});

上面我添加了一个策略,名字叫做Claim.Country.
因为不是默认,所以要[Authorize(Policy = "Claim.Country")]
policyBuilder 相当于上面的var defaultAuthBuilder = new AuthorizationPolicyBuilder();。
然后里面去设置起码有一个证书中要有国家。
policyBuilder 默认有一些限制可以使用,那么如何自己来定义呢?究竟是一种什么模式呢?

public class CustomRequireClaim:IAuthorizationRequirement
{
	public CustomRequireClaim(string ClainType)
	{
		this.ClainType = ClainType;
	}

	public string ClainType{ get; }
}

public class CustomRequireClaimHandler : AuthorizationHandler<CustomRequireClaim>
{
	protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequireClaim requirement)
	{
		var hasClaim = context.User.Claims.Any(u=>u.Type== requirement.ClainType);
		if (hasClaim)
		{
			context.Succeed(requirement);

		}
		return Task.CompletedTask;
	}
}

CustomRequireClaim 是什么呢?继承IAuthorizationRequirement。其实是模拟生活中的什么呢,比如说你要向批发商进一匹东西,有一些需求,比如说苹果要通红的,你就可以在这里填写。
CustomRequireClaimHandler 继承自AuthorizationHandler,批发商带一批货(程序也就是用户带着证书来了),你可以这个检查合格不合格,拿着你的需求表对照。
那么注册进入:

config.AddPolicy("Claim.Country", policyBuilder =>
{
	policyBuilder.AddRequirements(new CustomRequireClaim(ClaimTypes.Country));
});

同样需要:

services.AddScoped<IAuthorizationHandler, CustomRequireClaimHandler>();

这里就有疑问了,你这个policyBuilder.AddRequirements(new CustomRequireClaim(ClaimTypes.Country));就能调用到CustomRequireClaimHandler。
这个疑问简单化就是,你有一个需求,就只调用到检查类?
其实是在软件设计中,有这样一种套路,就是根据实体类,能自动调用执行类,这是一种设计模式。其实也能理解,就是呢,比如说公司有一张请假单,都标明是请假单了,肯定交给部门经理啊,AuthorizationHandler
就是标记,处理CustomRequireClaim的。
在里面其实只有IAuthorizationHandler,但是根据CustomRequireClaim能实例出CustomRequireClaimHandler。所以也需要加上:

services.AddScoped<IAuthorizationHandler, CustomRequireClaimHandler>();

同样,回过头来,看下面的。

policyBuilder.RequireClaim(ClaimTypes.Country);

如何做到直接点出来,不用这种add的方式呢?也就是说我也想实现这样的。

policyBuilder.RequireCustomClaim(ClaimTypes.Country);

我要能RequireCustomClaim然后可以调用到我给的限制.
下面是使用扩展的方式实现:

public static class AuthorizationPolicyBuilderExtensions
{
	public static AuthorizationPolicyBuilder RequireCustomClaim(this AuthorizationPolicyBuilder policyBuilder,string claimType)
	{
		policyBuilder.AddRequirements(new CustomRequireClaim(claimType));
		return policyBuilder;
	}
}

扩展一下AuthorizationPolicyBuilder 就可以,这样方便复用性。
以前的时候我们这样写:

[Authorize(Roles  = "admin")]

在这里就会检查我们的证书中是否有Roles 为admin。
然后呢,我们同样可以通过policy去实现。

config.AddPolicy("Claim.Role", policyBuilder =>
{
	policyBuilder.RequireClaim(ClaimTypes.Role, "admin");
});

限制需要admin也是可以的,然后[Authorize(Policy= "Claim.Role")]。
具体看自己需求。

总结

后续继续写自己对认证授权理解。以上均为个人理解,如有误差,请指正。

标签:Claim,Country,three,Authentication,var,new,policyBuilder,ClaimTypes,authorizatio
来源: https://www.cnblogs.com/qingfeng2022/p/13512169.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有