ASP.NET Core基于声明的访问控制到底是什么?
The following article is from 全栈码农画像 Author 小码甲
(给DotNet加星标,提升.Net技能)
转自:有态度的小码甲 cnblogs.com/JulianHuang/p/13725873.html
从ASP.NET 4.x到ASP.NET Core,内置身份验证已从基于角色的访问控制(RBAC)转变为基于声明的访问控制(CBAC)。
我们常用的HttpContext.User属性ASP.NET 4.0时代是IPrincipal类型,ASP.NETCore现在强化为ClaimsPrincipal类型。
本文就一起来看看这难缠的、晦涩难懂的声明式访问控制。
一、Claims : 声明
声明是基于声明的身份验证(claims-based authentication)的基础,声明是某主题(Subject)的片段信息
声明是以个名词,并不能说明主体可以做什么或不能做什么, 对应现实生活中各种卡片上体现的片段信息。
使用术语“主题”是因为声明不仅限于描述用户,声明可能与应用程序,服务或设备有关。
//声明通过`System.Security.Claim`类表示。
public class Claim {
public string Type { get; }
public string Value { get; }
public string ValueType { get; }
// some properties have been omitted.
}
对比可见:每个声明都有一个标识片段信息类型的Type属性、保存片段信息的Value属性、片段信息的数据类型。
var idClaim = new Claim(“Id”,“ 1”,“Integer”);
// 用户ID:整型
var dobClaim = new Claim(“dob”,“04/20/2000”,“Date”);
// 生日:事件类型
var emailClaim = new Claim(nameof(ClaimTypes.Name), mockUser.Email,nameof(ClaimValueTypes.String)),
二、Identities:身份
同一主题的声明组合在一起,称为ClaimsIdentity。
对应现实生活中各种卡片:身份证、工作狗牌、车牌、大保健会员卡,均体现了某一个主题。
public class ClaimsIdentity {
public string Name { get; }
public IEnumerable<Claim> Claims { get; }
public string AuthenticationType { get; }
//保存使用的身份验证方法(Bearer、Basic)
public bool IsAuthenticated { get; }
// some properties have been omitted.
}
某WebAPI,该API可通过其唯一ID和名称来识别用户。验证从用户收到的承载令牌(JWT等)后,我们可以创建ClaimsIdentity来表示它们:
ClaimsIdentity userIdentity = new ClaimsIdentity(
new Claim[] {
new Claim("Id", "1"),
new Claim("Username", "Bert")
},
"Bearer"
);
//userIdentity.IsAuthenticated == true since we passed "Bearer" as AuthenticationType.
三、Principals: 主体
ClaimsIdentity可以方便地表示一个主题(一组声明),很多时候一个主体有多个身份,就像现实生活中我们有个身份卡片,这个时候我们就需要钱包或者账号管理工具(1Passwowd、LassPass)
接上面的例子, 如果WebAPI需要确保访客使用的设备处于白名单,则可以对访客维护设备身份:
ClaimsIdentity deviceIdentity = new ClaimsIdentity(
new Claim[] {
new Claim("IP", "192.168.1.1"),
new Claim("Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
}
);
// 针对访客设备声明,不要设置AuthenticationType
将用户身份和设备身份两个独立的身份集中在一起就是主体ClaimsPrincipal
public class ClaimsPrincipal {
public IEnumerable<Claim> Claims { get; }
public IEnumerable<ClaimsIdentity> { get; }
public ClaimsIdentity Identity { get; }
public virtual IEnumerable<Claim> FindAll(Predicate<Claim> match);
public virtual bool HasClaim(string type, string value);
// ClaimsPrincipal提供了一些辅助方法/属性来检查事物,例如在任何关联的身份中是否存在声明.
}
主体对象代表代码运行的用户的安全上下文,是各种有效身份的组合。
var principal = new ClaimsPrincipal(new IIdentity[] { userIdentity, deviceIdentity });
总结
基于声明的访问控制,本质是将散落的各个主题身份收集起来,自行表征。
Claims:身份信息的片段数据
Identities:各种身份信息
Principals:主体,各种身份账户的集中存储地
https://github.com/dotnet/runtime/blob/master/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsIdentity.cs
https://eddieabbondanz.io/post/aspnet/claims-based-authentication-claims-identities-principals/
- EOF -
看完本文有收获?请转发分享给更多人
关注「DotNet」加星标,提升.Net技能
好文章,我在看❤️