前言

在上一篇文章中,我们学习了 CookieAuthentication 中间件,本篇的话主要看一下 Identity 本身。

最早2005年 ASP.NET 2.0 的时候开始, Web 应用程序在处理身份验证和授权有了很多的变化,多了比如手机端,平板等,所以那个时候为了适应这种变化就引入了ASP.NET Membership,但是随着时间的发展一些社交网站或者程序聚集了大量的用户,比如Facebook,Twitter,QQ等,这个时候用户希望能够使用他们在这些社交站点身份来登陆当前网站,这样可以免除注册这些琐碎而又必要的操作,用户也不必记住大量的账户密码。

又随着互联网的发展,越来越多的开发者不只是关注具体业务代码的编写,转变为开始关注应用程序代码的单元测试,这已经是开发者关注的核心。所以在2008年,ASP.NET 团队引入了 MVC 框架,这样来帮助开发者很方便的构建单元测试,同时开发者希望他们的 Membership 系统也能够做到这一点。

基于以上,ASP.NET Identity 应运而生。

Identity 要解决的问题

很多开发人员说他们不愿意使用Identity,自己实现要方便的多,OK,那么需求来了?以下就是我针对此次任务给你提出来的需求。

身份系统

  • 可以同时被所有的ASP.NET 框架使用(Web MVC,Web Forms,Web Api,SignalR)

  • 可以应用于构建 Web, 手机,存储,或者混合应用。

能够对用户资料(User Profile)很方便的扩展

  • 可以针对用户资料进行扩展。

持久化

  • 默认把用户信息存储在数据库中,可以支持使用EF进行持久化。(可以看到,EF 其实只是Identity的一个功能点而已

  • 可以控制数据库架构,更改表名或者主键的数据类型(int,string)

  • 可以使用不同的存储机制(如 NoSQL,DB2等)

单元测试

  • 使WEB 应用程序可以进行单元测试,可以针对ASP.NET Identity编写单元测试

角色机制

  • 提供角色机制,可以使用不同的角色来进行不同权限的限制,可以轻松的创建角色,向用户添加角色等。

要支持基于Claims

  • 需要支持基于 Claims 的身份验证机制,其中用户身份是一组Claims,一组Claims可以比角色拥有更强的表现力,而角色仅仅是一个bool值来表示是不是会员而已。

第三方社交登陆

  • 可以很方便的使用第三方登入,比如 Microsoft 账户,Facebook, Twitter,Google等,并且存储用户特定的数据。

封装为中间件

  • 基于中间件实现,不要对具体项目产生依赖

  • 基于 Authorzation 中间件实现,而不是使用 FormsAuthentication 来存储cookie。

NuGet包提供

  • 发布为 Nuget 包,这样可以容易的进行迭代和bug修复,可以灵活的提供给使用者。

以上,就是我提出来的需求,如果让你来封装这样一个用户身份认证组件,你会不是想到以上的这些功能点,那针对于这些功能点你又会怎么样来设计呢?

下面来看一下 Identity 怎么样设计的吧。

Getting Started

抽丝剥茧,我们先从入口看一下其使用方式。 首先我们打开 Startup.cs 文件,然后添加如下代码:

public class Startup{    public void ConfigureServices(IServiceCollection services)    {services.AddDbContext<ApplicationDbContext>(options =>options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));services.AddIdentity<ApplicationUser, IdentityRole>(options => {options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";options.Cookies.ApplicationCookie.CookieName = "Interop";}).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();}    public void Configure(IApplicationBuilder app)    {        // 使用了 CookieAuthentication 中间件做身份认证app.UseIdentity();}
}

在 ConfigureServices 中,先是注册了数据库上下文,然后又 services.AddIdentity() 我们看一下里面都注册了哪些服务呢?

public static IdentityBuilder AddIdentity<TUser, TRole>(this IServiceCollection services,Action<IdentityOptions> setupAction)where TUser : classwhere TRole : class{    // 这个就是被 Identity 使用的services.AddAuthentication(options =>{        // This is the Default value for ExternalCookieAuthenticationSchemeoptions.SignInScheme = new IdentityCookieOptions().ExternalCookieAuthenticationScheme;});    // 注册 IHttpContextAccessor ,会用到services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();    // Identity servicesservices.TryAddSingleton<IdentityMarkerService>();services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();    // 错误描述信息services.TryAddScoped<IdentityErrorDescriber>();services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();    //身份当事人工厂services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();    //三大对象services.TryAddScoped<UserManager<TUser>, UserManager<TUser>>();services.TryAddScoped<SignInManager<TUser>, SignInManager<TUser>>();services.TryAddScoped<RoleManager<TRole>, RoleManager<TRole>>();if (setupAction != null){services.Configure(setupAction);}return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
}    

看了以上代码后,基本上知道了 Identity 他的设计的一个架构了,通过此结构我们也能够学习到我们自己封装一个中间件的时候,该怎么样来组织我们的代码结构,怎么样的利用 ASP.NET Core 给我们提供的依赖注入来更好的解耦,下面我们来看一下通过以上代码我们能够学到什么东西:

1、 在 public static IdentityBuilder AddIdentity<TUser, TRole>(this IServiceCollection services, Action<IdentityOptions> setupAction)这个扩展方法中,提供了一个参数 Action<IdentityOptions>,这个是干什么用的呢? 这个是我们在设计一个中间件的时候,有需要外部提供的参数,就会设计一个 Options 的类用来接受外部的参数,然后封装为一个Action委托的方式提供。在使用到的地方就可以以 IOption xxx 的形式注入进来使用了。

2、services.TryAddScoped<Interface,Implement>(),这个注册方式就是说,如果检测到DI容器里面已经有了当前要注册的Interface或者Service,就不会再次注册,没有才会注册进去。 那么为什么此处要这样用呢? 这是因为如果用户已经实现了此接口并且已经注册的容器当中的话,就使用用户注册的,而不是中间件自身的。用户就能很好的对中间件提供的功能进行自定义了,这就是OO中的多态性,这就是里氏替换原则。

3、如果你能理解第2条的话,那么你应该知道为什么会在服务中注册 错误描述信息 那个IdentityErrorDescriber 了吧,也能够解决你想提示账号密码错误,无奈Identity输出是英文问题的提示。

4、三大对象,这个是 Identity 的核心了,所以学习 Identity 的话,在看完博客 ASP.NET Core 之 Identity 入门(一,二)之后,学这三个对象就够了。

SignInManager: 主要处理注册登录相关业务逻辑。

UserManager: 处理用户相关添加删除,修改密码,添加删除角色等。

RoleManager:角色相关添加删除更新等。

有些同学可能很好奇,都没有依赖具体的数据库或者是EF,是怎么样做到的增删改查的呢?

这个时候,就需要几个 Store 接口派上用场了。以下是Identity中定义的Store接口:

  • IQueryableRoleStore

  • IQueryableUserStore

  • IRoleClaimStore

  • IRoleStore

  • IUserAuthenticationTokenStore

  • IUserClaimStore

  • IUserEmailStore

  • IUserLockoutStore

  • IUserLoginStore

  • IUserPasswordStore

  • IUserPhoneNumberStore

  • IUserRoleStore

  • IUserSecurityStampStore

  • IUserStore

  • IUserTwoFactorStore

有了这些接口之后,是不是豁然开朗了,原来 Identity 是通过这种方式实现的持久化机制,依赖抽象接口而不是依赖具体的细节实现,这就是面向对象中的依赖倒置原则呀。

Identity 和 EntityFramework

Identity 和 EntityFramework的关系,相信上个章节看懂了之后,就很容易明白了,对的,EF 只是针对于上述 Store 接口的实现,不信你看截图的源码:

Identity 打头的那些类文件都是定义的需要持久化的Entity对象,Store结尾的那些就是接口的实现啦。

第三方的 Identity 实现

除了 EF 是官方默认提供的持久化库之外,还有一些第三方的库,当然你也可以自己使用 ADO.NET 或者 Drapper 实现。

MangoDb 针对于 Identity 提供的实现: https://github.com/tugberkugurlu/AspNetCore.Identity.MongoDB

LinqToDB 针对于 Identity 提供的实现:https://github.com/linq2db/LinqToDB.Identity

总结

这篇博文写了蛮久的时间的,一方面是因为在构思怎么样的思路来让大家更好的理解,而不仅仅是使用。因为有太多的文章介绍Identity 的使用方式以及代码了,但是最后大家还是不会用。后来想到如果让别人想要理解你的库也好代码也好,让其知道诞生的背景是很重要的,因为这才是设计的初衷。另一方面是因为Connect() 2016 大会上,.NET Core 发布了 1.1 版本,除了把项目升级到1.1之外,也在学习1.1新的一些东西,以便更好给大家分享。

相关文章:

  • ASP.NET Core 之 Identity 入门(一)

  • ASP.NET Core 之 Identity 入门(二)

  • ASP.NET Identity登入技术应用

  • Web API 基于ASP.NET Identity的Basic Authentication

  • ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇

原文地址:http://www.cnblogs.com/savorboard/p/aspnetcore-identity3.html

.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

ASP.NET Core 之 Identity 入门(三)相关推荐

  1. ASP.NET Core 之 Identity 入门(二)

    前言 在 上篇文章 中讲了关于 Identity 需要了解的单词以及相对应的几个知识点,并且知道了Identity处在整个登入流程中的位置,本篇主要是在 .NET 整个认证系统中比较重要的一个环节,就 ...

  2. 深入浅出 ASP.NET Core 与 Docker 入门课程说明

    点击蓝字"角落的白板报"关注我哟 加个"星标★",好文必达! 深入浅出 ASP.NET Core 与 Docker 入门课程说明 <深入浅出 ASP.NE ...

  3. netcore docker_深入浅出 ASP.NET Core 与 Docker 入门课程目标说明

    课程目标说明https://www.zhihu.com/video/1241137370310508544 <深入浅出 http://ASP.NET Core 与 Docker >是一门新 ...

  4. 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面

    原文:学习ASP.NET Core Razor 编程系列三--创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 ...

  5. ASP.NET Core MVC从入门到精通[PDF版]

    随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用 ...

  6. ASP.NET Core MVC 从入门到精通之初窥门径

    随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用 ...

  7. ASP.NET Core MVC 从入门到精通之路由

    随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用 ...

  8. Asp.Net Core之Identity应用(下篇)

    一.前言 在上篇中简单介绍了 Asp.Net Core 自带的 Identity,一个负责对用户的身份进行认证的框架,当我们按需选择这个框架作为管理和存储我们应用中的用户账号数据的时候,就会添加到自己 ...

  9. 如何基于asp.net core的Identity框架在mysql上作身份验证处理

    首先了解这个概念,我一开始也是理解和掌握基本的概念,再去做程序的开发.Identity框架是微软自己提供,基于.net core平台,可拓展.轻量 级.面向多个数据库的身份验证框架.IdentityS ...

最新文章

  1. VUE 动态给对象增加属性,并触发视图更新。
  2. ESXi上的固态硬盘识别为非SSD
  3. json转php数组 在线,PHP如何将JSON转换成数组/对象
  4. Nginx反向代理+Go服务实践
  5. SaltStack 第一板块入门介绍 [1]
  6. 开关电源之PCB安规设计规范
  7. h5跳转小程序页面url_小程序和h5跳转
  8. 使用java.text包格式化数字和日期
  9. 开源代码实现pppoe over l2tp方案
  10. JavaScript的js文件压缩和格式化工具
  11. 2022电大国家开放大学网上形考任务-农业微生物学非免费(非答案)
  12. excel单个对象用poi导出,并设置每个sheet得最大行数防止报错
  13. win10輸入法去掉语言栏?win10輸入法切换简体繁体?
  14. 【UE4】蓝图转为C++官方教程部分笔记
  15. awk 分隔符_awk 命令快速入门
  16. auto dvr使用教程_电缆盒和DVR真的使用那么多功率吗?
  17. Redis 数据库keys 命令的模糊查询
  18. java学习笔记day09 final、多态、抽象类、接口
  19. * IO原理剖析-装饰器设计模式(1)
  20. 获取联想锁屏壁纸方法

热门文章

  1. ArcGISServer10安装与地图发布
  2. 聚类算法学习指南(二)
  3. javascript常用技巧
  4. 战神II导演 首席程序员访谈(转自www.npc6.com )
  5. .NET 6新特性试用 | DateOnly和TimeOnly类型
  6. .NET MAUI 预览版 6 发布
  7. Newbe.Claptrap 0.10.2 发布,Blazor 演示
  8. 二分查找和折半插入排序一块说说-很合适~~~
  9. 【One by One系列】IdentityServer4(二)使用Client Credentials保护API资源
  10. 文章目录 | .NET Core on K8s学习之旅 (更新至20200618)