ASP.NET Core 基于声明的访问控制到底是什么鬼?
从ASP.NET 4.x到ASP.NET Core,内置身份验证已从基于角色的访问控制(RBAC)转变为基于声明的访问控制(CBAC)。
我们常用的HttpContext.User属性ASP.NET 4.0时代是IPrincipal类型,ASP.NETCore现在强化为ClaimsPrincipal类型。

本文就一起来看看这难缠的、晦涩难懂的声明式访问控制。
1.Claims : 声明
声明是基于声明的身份验证(claims-based authentication)的基础,声明是某主题(Subject)的片段信息
声明是以个名词,并不能说明主体可以做什么或不能做什么, 对应现实生活中各种卡片上体现的片段信息。
使用术语“主题”是因为声明不仅限于描述用户,声明可能与应用程序,服务或设备有关。
| 主题 | Claim1 | Claim2 | Claim3 | Claim3 | Claim5 | Claim6 | Claim7 | Claim8 |
|---|---|---|---|---|---|---|---|---|
| 身份证 | 身份证号 | 姓名 | 性别 | 籍贯 | 生日 | 签发机关 | 签发时间 | 过期时间 |
| 工作狗牌 | 姓名 | 级别 | 花名 | 身份证号 | 性别 | base地区 | 入职时间 | --- |
| 王者荣耀 | 账号 | 游戏等级 | 大区 | 角色 | 氪金级别 | 年龄 | 注册时间 | --- |
| 微信 | 微信号 | 昵称 | 注册时间 | 国籍 | 实名证件 | 手机号 | --- | --- |
| 车牌 | 车牌编号 | 车牌所属人 | 车牌地区 | 车牌性质 | 签发时间 | 签发机关 | --- | --- |
| 某大保健会员卡 | 卡号 | 姓名 | 手机号 | 会员级别 | 办卡时间 | 办卡门店 | --- | --- |
// 声明通过`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)),
2. 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.
3. 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://eddieabbondanz.io/post/aspnet/claims-based-authentication-claims-identities-principals/
ASP.NET Core 基于声明的访问控制到底是什么鬼?的更多相关文章
- ASP.NET Core 基于JWT的认证(二)
ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...
- ASP.NET Core 基于JWT的认证(一)
ASP.NET Core 基于JWT的认证(一) Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计 ...
- Asp.Net Core基于JWT认证的数据接口网关Demo
近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...
- ASP.NET Core基于K8S的微服务电商案例实践--学习笔记
摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...
- Asp.net Core基于MVC框架实现PostgreSQL操作
简单介绍 Asp.net Core最大的价值在于跨平台.跨平台.跨平台.重要的事情说三遍.但是目前毕竟是在开发初期,虽然推出了1.0.0 正式版,但是其实好多功能还没有完善.比方说编译时的一些文件编码 ...
- ASP.NET Core - 基于IHttpContextAccessor实现系统级别身份标识
问题引入: 通过[ASP.NET Core[源码分析篇] - 认证]这篇文章中,我们知道当请求通过认证模块时,会给当前的HttpContext赋予当前用户身份标识,我们在需要授权的控制器中打上[Aut ...
- 理解ASP.NET Core - 基于Cookie的身份认证(Authentication)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 概述 通常,身份认证(Authentication)和授权(Authorization)都会放 ...
- 理解ASP.NET Core - 基于JwtBearer的身份认证(Authentication)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 在开始之前,如果你还不了解基于Cookie的身份认证,那么建议你先阅读<基于Cookie ...
- Asp.Net Core基于Cookie实现同域单点登录(SSO)
在同一个域名下有很多子系统 如:a.giant.com b.giant.com c.giant.com等 但是这些系统都是giant.com这个子域. 这样的情况就可以在不引用其它框架的情况下, ...
随机推荐
- First-Spike-Based Visual Categorization Using Reward-Modulated STDP
郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 强化学习(RL)最近以击败欧洲围棋冠军等重大成就重新受到欢迎.在这里,我们第一次表明,RL可以有效地用于训练一个脉冲神经 ...
- 「从零单排canal 07」 parser模块源码解析
基于1.1.5-alpha版本,具体源码笔记可以参考我的github:https://github.com/saigu/JavaKnowledgeGraph/tree/master/code_read ...
- ORA-01455: converting column overflows integer datatypes.
系统执行抛了一个ORA-01455: converting column overflows integer datatypes.把当时执行的SQL取出来,在plsql developer里面执行是没 ...
- laravel中elastisearch安装和测试运行是否成功(注意是windows下的操作)
1.去elasticsearch官网下载,如果太慢可以在我上一个随笔看下载地址 2.下载完解压缩,在cmd中找到到elasticsearch的bin目录下执行.\elasticsearch.bat - ...
- 如何用python制作贪吃蛇以及AI版贪吃蛇
用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...
- 【Android】AndroidStudio(Eclipse)如何使用天天模拟器进行调试apk应用。
作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 大家都知道,我们这些Android开 ...
- 双击Back退出应用 android中弹出吐司
第一种方法: public void onBackPressed() { if (isState) { //isState初始值为true isState = false; Toast.makeTex ...
- Mac上如何降级Java版本
升级到了Java9,有些工具就不工作了.因此要降级到Java8.方法: /Library/Java/JavaVirtualMachines/下的高版本SDK即可
- JAVA 各种锁机制
可重入锁 可重锁是指同一个线程,外层函数获取锁后,内层函数可以自动获取到锁. java中synchronized和ReentrantLock都是可重入锁. 对于synchronized,其实现机制有j ...
- Palindrome subsequence(区间dp+容斥)
In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting so ...