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可通过其唯一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),将各种身份集中在一起就是主体ClaimsPrincipal
。
接上面的例子, 如果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
主体对象代表代码运行的用户的安全上下文,是各种有效身份的组合。
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 });
总结
基于声明的身份验证是WebApp获取它们需要的组织内部、其他组织以及Internet上的用户的身份信息的常用方法。它还为本地或云中运行的应用程序提供了一致的方法。基于声明的身份验证将身份和访问控制的各个元素抽象为两个部分:声明的概念以及颁发者或授权机构的概念。[
- Claims: 身份信息的片段数据
- Identities:各种身份卡片
- Principals:主体,各种身份账户的集中存储地
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 基于OpenCV的图像卡通化
- shadertoy绘图
- 单基因生信分析流程(6)单基因相似性分析
- 三阴性乳腺癌提取和分析
- 一日一技:更友好的格式化数据提取方案
- 『深度应用』YoloV5 RTX2080Ti TensorRT与PyTorch速度对比
- 0797-使用HDP或CDP的Atlas采集CDH6的元数据和血缘
- 现代通信理论与新技术 PPT笔记整理
- 找找规律——LeetCode题目6:Z字形变换
- 给你点信心——LeetCode题目7:整数反转
- Python -二叉树 创建与遍历算法(很详细,转自国外教程)
- APP流量来源追踪方式——Android篇
- 从浏览器输入网址回车到看到页面过程到底经历了什么?
- Flutter Bloc 官方文档(BlocBuilder翻译)
- OpenGL ES 3.0 | 统一变量和属性的概念与(在程序中的)获取流程、统一变量缓冲区对象详解、std140块规范、用 命名统一变量块 建立 统一变量缓冲区对象 的流程 和 相关API 和...