详解ASP.NET Core 之 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 : class where TRole : class { // 这个就是被 Identity 使用的 services.AddAuthentication(options => { // This is the Default value for ExternalCookieAuthenticationScheme options.SignInScheme = new IdentityCookieOptions().ExternalCookieAuthenticationScheme; }); // 注册 IHttpContextAccessor ,会用到 services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); // Identity services services.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); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjyyjz.html