ASP.NET Core 基于声明的访问控制到底是什么鬼?

dotNET全栈开发

共 3069字,需浏览 7分钟

 ·

2020-09-25 22:23

从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)的片段信息

声明是个名词,并不能说明主体可以做什么或不能做什么, 对应现实生活中各种卡片上体现的片段信息。
使用术语“主题”是因为声明不仅限于描述用户,声明可能与应用程序,服务或设备有关。

主题Claim1Claim2Claim3Claim3Claim5Claim6Claim7Claim8
身份证身份证号姓名性别籍贯生日签发机关签发时间过期时间
工作狗牌姓名级别花名身份证号性别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 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 Claims { get; }
  public IEnumerable { get; }
  public ClaimsIdentity Identity { get; }
  public virtual IEnumerable FindAll(Predicate match);
  public virtual bool HasClaim(string type, string value);
  // ClaimsPrincipal提供了一些辅助方法/属性来检查声明.
}

 var principal = new ClaimsPrincipal(new IIdentity[] { userIdentity, deviceIdentity });

总结

基于声明的身份验证是WebApp获取它们需要的组织内部、其他组织以及Internet上的用户的身份信息的常用方法。它还为本地或云中运行的应用程序提供了一致的方法。基于声明的身份验证将身份和访问控制的各个元素抽象为两个部分:声明的概念以及颁发者或授权机构的概念。[

  1. Claims: 身份信息的片段数据
  2. Identities:各种身份卡片
  3. Principals:主体,各种身份账户的集中存储地

回复 【关闭】广
回复 【实战】获取20套实战源码
回复 【被删】
回复 【访客】访
回复 【小程序】学获取15套【入门+实战+赚钱】小程序源码
回复 【python】学微获取全套0基础Python知识手册
回复 【2019】获取2019 .NET 开发者峰会资料PPT
回复 【加群】加入dotnet微信交流群

微信竟然可以查出行轨迹了,预计又一波情侣要分手?


一款开源的.NET Core爬虫神器:DotnetSpider


浏览 34
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报