原文:用例子看ASP.NET Core Identity是什么?

@

前言

有三个重要的类Claim, ClaimsIdentity, ClaimsPrincipal,我们以一个持有合法证件的学生Bob做比方,ClaimsPrincipal就是持有证件的学生Bob,ClaimsIdentity就是学生Bob的证件驾照,Claim就是Bob驾照中的各种信息。

下边就开始围绕上边这段话展开描述:

基于声明的认证(Claims-based Authentication)

在开始学习标识管理系统(Identity system)之前,很有必要搞清楚什么是基于声明的身份认证。

我们假设一个场景。Bob是一名大学生,准备去银行为自己开户。银行工作人员需要Bob提供他的有效证件,于是Bob就把自己的驾照提供给了银行工作人员。银行工作人员可以从驾照上获取到Bob的个人信息,例如姓名、出生日期和地址等。

Bob希望能够享受到银行针对大学生的优惠政策,于是银行工作人员又请Bob提供了学生证,同时从上边可以获取到姓名、所在的大学名称、院系以及学号等信息。(这里提供别人的学生证一定是不行的!)

使用以上生活中典型的应用场景,可以帮助我们进一步去理解基于声明(Claims-based Authentication)的身份认证。这个例子中Bob拥有两个标识(Identity,就相当于有效的身份证明,即证明你是你的那张纸,也就是Identity):驾照+学生证。(当然还可以提供更多的Identity,比如护照、户口本等等。)

好吧,我自己用文字越写越怕不明白,通过上边的这些文字,只需要清楚这么几点内容:

Claim

  • 就是一个键值对,例如:name:Bob
  • Claim可以是姓名、出身日期、地址、所在大学、学号等等信息

    Identity

  • 很多条Claim组成了一个Identity
  • Identity就是一个有效的身份证明 = 证明你是你的那张纸 = 驾照、学生证等等
  • 一个人可以拥有很多个Identity



Bob去开户,先提供了一个Identity(这里就是驾照),接着又提供了一个Identity(学生证)

清楚了这些,我们继续看

在ASP.NET Core Identity中是如何实现的

ASP.NET Core 是开源的,这能够让我们非常方便的去学习和理解它是如何构成并运行的。源码可以去github上查看

可以把源码下载下来,然后查看源码,路径为:

corefx-master(解压后主文件夹)/src/System.Security.Claims/src/System/Security

类ClaimsPrincipal

一个用户(User)被声明成ClaimsPrincipal类型(继承自IPrincipal接口)。ClaimsPrincipal类来自System.Security.Claims命名空间。

public class ClaimsPrincipal : IPrincipal
{
...........
...........
public virtual IIdentity Identity { get; }
public virtual IEnumerable<ClaimsIdentity> Identities { get; }
public virtual IEnumerable<Claim> Claims { get; }
...........
...........
public virtual bool HasClaim(Predicate<Claim> match);
public virtual bool HasClaim(string type, string value);
public virtual bool IsInRole(string role);
...........
...........
}

从ClaimsPrincipal类中可以看到有一个返回类型为ClaimsIdentity集合的Identities属性,代表着一个User可以拥有多个Identity。

在这里的另外一个属性Identity,不要被迷惑,他返回的是ClaimsPrincipal中主要的(如果有多个)那一个ClaimIdentity。

另外一个重要的属性Claims,它返回了一个在ClaimsPrincipal中所有的ClaimsIdentity所包含得全部Claims的集合。

考察另外一个重要的类ClaimsIdentity

public class ClaimsIdentity : IIdentity

{

...........

...........

public virtual string AuthenticationType { get; }

public virtual string Name { get; }

public virtual bool IsAuthenticated { get; }

public virtual IEnumerable Claims { get; }

public virtual IEnumerable FindAll(Predicate match);

public virtual Claim FindFirst(string type);

public virtual bool HasClaim(string type, string value);

...........

...........

}

  • 这里的AuthenticationType属性从字面意思就能很好的理解,返回认证的类型,在本示例中就可能是驾照或者学生证。在ASP.NET Core 中也可能是例如:微信、QQ、Cookies、Basic、Windows、Google等等。用AuthenticationType来验证和确定与身份相关联的声明用的什么方法。
  • 还有一个IsAuthenticated属性,用来获取Identity是否被验证,大家可能会感觉多余,在没有通过验证的时候又怎么会得到一个拥有Claims的Identity呢?有一个典型应用场景就是,允许游客访问你的网站,允许使用购物车。这个游客一样拥有由声明(Claims)组成的标识(Identity),只是这位游客还没有被验证。这一非常重要的区别需要牢记。

    在ASP.NET Core 创建一个ClaimsIdentity的时候,IsAuthenticationType总会被初始化为true。一个通过验证的用户一定会是true,相反未被验证的游客,此属性为false。
  • Claims是组成Identity的全部Claim集合。

现在我们把这个假设的应用场景用图示再总结一下:

在ASP.NET Core Identity中一同运行

上述内容在ASP.NET Core Identity 中使用Identity对象的简单交互已经创建了一些API,例如SignInManager, UserManager ,RoleManager等,在ASP.NET Core 项目中通过依赖注入就可以使用它们。

例如,登录管理就通过下边一个public方法来完成登录:

public virtual async Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties,
string authenticationMethod = null)
{
var userPrincipal = await CreateUserPrincipalAsync(user);
if (authenticationMethod != null)
{
userPrincipal.Identities.First().AddClaim(new Claim
(ClaimTypes.AuthenticationMethod, authenticationMethod));
}
await Context.SignInAsync(IdentityConstants.ApplicationScheme,
userPrincipal,
authenticationProperties ?? new AuthenticationProperties());
}

总结

  • Claim就是一个键值对,用来描述一个特新,比如姓名:Bob就是一个Claim,生日:2009.9.15这也是一个Claim。其中姓名或生日就是这个Claim的一种类型,即Claimtype。
  • 一组claim就构成了一个identity,具有这些claims的identity就是 ClaimsIdentity ,也可以把ClaimsIdentity理解为“证件”,驾照就是一种ClaimsIdentity,学生证也是一种ClaimIdentity。
  • ClaimsIdentity的持有者就是ClaimsPrincipal ,一个ClaimsPrincipal可以持有多个ClaimsIdentity,就比如Bob既持有驾照(ClaimIdentity),又持有身份证(ClaimIdentity)。

    理解了Claim, ClaimsIdentity, ClaimsPrincipal这三个概念,就能理解生成登录Cookie为什么要用下面的代码?
...
var claimsIdentity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, loginName) }, "Basic");
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
await context.Authentication.SignInAsync(_cookieAuthOptions.AuthenticationScheme, claimsPrincipal);
...

要用Cookie代表一个通过验证的主体,必须包含Claim, ClaimsIdentity, ClaimsPrincipal这三个信息,以一个持有合法驾照的人做比方,ClaimsPrincipal就是持有证件的人Bob,ClaimsIdentity就是证件驾照,"Basic"就是证件类型(这里假设是驾照),Claim就是驾照中的信息。

如果感觉困扰,可以再看下dudu博客的这篇文章

这篇教程中,因为自己在理解的时候花了不少时间,请大家指证!

用例子看ASP.NET Core Identity是什么?的更多相关文章

  1. ASP.NET Core Identity Hands On(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  2. ASP.NET Core Identity 实战(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  3. ASP.NET Core Identity 实战(4)授权过程

    这篇文章我们将一起来学习 Asp.Net Core 中的(注:这样描述不准确,稍后你会明白)授权过程 前情提要 在之前的文章里,我们有提到认证和授权是两个分开的过程,而且认证过程不属于Identity ...

  4. 用一个应用场景理解ASP.NET Core Identity是什么?

    目录 前言 基于声明的认证(Claims-based Authentication) 应用场景一 在ASP.NET Core 中Identity是如何实现的 类ClaimsPrincipal 考察另外 ...

  5. IdentityServer(12)- 使用 ASP.NET Core Identity

    IdentityServer具有非常好的扩展性,其中用户及其数据(包括密码)部分你可以使用任何想要的数据库进行持久化. 如果需要一个新的用户数据库,那么ASP.NET Core Identity是你的 ...

  6. ASP.NET Core Identity Hands On(1)——Identity 初次体验

    ASP.NET Core Identity是用于构建ASP.NET Core Web应用程序的成员资格系统,包括成员资格.登录和用户数据存储 这是来自于 ASP.NET Core Identity 仓 ...

  7. ASP.NET Core Identity 迁移数据 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Identity 迁移数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 迁移数据 上一章节中我们配置了 ...

  8. ASP.NET Core Identity自定义数据库结构和完全使用Dapper而非EntityFramework Core

    前言 原本本节内容是不存在的,出于有几个人问到了我:我想使用ASP.NET Core Identity,但是我又不想使用默认生成的数据库表,想自定义一套,我想要使用ASP.NE Core Identi ...

  9. Asp.Net Core Identity 隐私数据保护

    前言 Asp.Net Core Identity 是 Asp.Net Core 的重要组成部分,他为 Asp.Net Core 甚至其他 .Net Core 应用程序提供了一个简单易用且易于扩展的基础 ...

随机推荐

  1. 分库分表中间件Sharding-JDBC

    数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据和高并发对 ...

  2. Linux 安装软件的几种方式

    目录 几种安装方式 源代码编译安装 借助软件包管理器安装 二进制格式安装 总结 参考 几种安装方式 源代码编译安装 源代码包的安装一般为下载软件源代码,然后编译安装.常见的 C 程序软件的安装步骤是 ...

  3. HDU 1241 Oil Deposits【DFS】

    解题思路:第一道DFS的题目--- 参看了紫书和网上的题解-- 在找到一块油田@的时候,往它的八个方向找,直到在能找到的范围内没有油田结束这次搜索 可以模拟一次DFS,比如说样例 在i=0,j=1时, ...

  4. 查看锁表进程SQL语句

    查看锁表进程SQL语句   set pagesize 999 set line180 col ORACLE_USERNAME for a18 col OS_USER_NAME for a18 col ...

  5. Dapper优秀资料

    dapper extensions (predicates) https://www.cnblogs.com/starluck/p/4542370.html

  6. (转)Java 虚拟机体系结构

    来源:http://hxraid.iteye.com/blog/676235 众所周知,Java源代码被编译器编译成class文件.而并不是底层操作系统可以直接执行的二进制指令(比如Windows O ...

  7. scrapy框架学习

    一.初窥Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网 ...

  8. java 模拟ajax上传图片

    1.maven 引入依赖 <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime --> &l ...

  9. Ubuntu 如何进入系统文件/etc/profile修改内容

    转载:https://blog.csdn.net/cfq1491/article/details/81088117 /etc/profile 默认权限为 -rw-r--r-- 即只有root用户可以修 ...

  10. Windows 10用户可以快速移除U盘

    新浪科技讯,北京时间 4 月 9 日上午消息,据美国科技媒体 The Verge 报道,微软再次证实,从 1809 版本的 Windows 10 开始,插入新闪存盘时“快速移除”(quick remo ...