ASP.NET Identity除了提供基于Cookie的身份验证外,还提供了一些高级功能,如多次输入错误账户信息后会锁定用户禁止登录、集成第三方验证、账户的二次验证等,并且ASP.NET MVC的默认模板中就带有这些功能。
本文将从以下几个方面解释ASP.NET Identity是如何实现身份验证机制的:
● ASP.NET Identity的“多重”身份验证
● Owin身份验证的积极模式与消极模式
● 再谈Owin身份验证机制
● 基于Owin的Identity在ASP.NET中身份验证的解决方案
为什么本章以Identity的多重身份验证为题?因为ASP.NET Identity是基于Owin通过中间件的形式实现的身份验证,以下是默认模板中添加的代码:
从代码中可以看到,模板代码一共添加了7个(包含被注释的3个)身份验证相关的中间件,按照对Owin中间件的理解,当一个请求进入Owin管道后,每一个中间件都会被执行,上面的身份验证中间件按照功能来分有基于Cookie的、有基于外部Cookie的、双因子验证的以及第三方账户登录(被注释的代码)的,这就意味着每一个请求都会被这些中间件一一处理,所以称其为“多重”身份验证。
本文从标题到现在的“多重”均是打引号的,说明Identity中的验证并不像表面那样多个功能堆叠那么简单,接下来就从身份验证的积极模式与消极模式开始来消除Identity在ASP.NET身份验证中的迷雾。
Identity是基于Owin实现身份验证的,所以实际上Owin才是身份验证规则的制定者,Identity只不过是实现的一种,在Owin中把身份验证中间件分为两个模式,分别是积极模式与消极模式,两个模式是通过一个名为AuthenticationMode的枚举类型定义的:
根据代码注释得到对积极模式以及消极模式的介绍如下:
● 积极模式(Active):积极模式的身份验证中间件将在请求到达时对用户身份信息进行修改,同时当响应状态为401时会处理响应信息。
● 消极模式(Passive):该模式下的中间件只有需要或者说显式调用的情况下才会使用该中间件包含的方法对请求进行验证,包括当出现401情况时也需要在拓展的Challenge数据中找到对应的验证类型名称匹配后才会调用处理。
一句话来说就是无论在Owin管道中添加多少个身份验证中间件,在处理请求时都只有验证模式为积极的才会对请求进行处理,其它的都需要通过手动的方式来调用。为什么?看后面内容。
再谈Owin身份验证机制前面的文章中介绍了Owin与Identity是如何集成的如《ASP.NET没有魔法——Identity与Owin》、《ASP.NET没有魔法——ASP.NET Identity的加密与解密》等文章,但主要是介绍Identity如何通过中间件的方式添加到Owin管道对用户身份信息验证以及基于Cookie的身份验证中间件做了什么工作,最核心的点还未提到,那就是整个身份验证的机制或者说规则是由Owin(Katana)来定的,Identity只不过是遵循这个规则的一个实现甚至可以说只是一个使用者,因为它仅仅是为Cookie验证中间件提供了用户数据,然后通过依赖AuthenticationManager来实现、拓展了ASP.NET中的身份验证功能。
上面是Owin身份验证相关的包图,从这个图中可以得出以下结论:
1. Micrsosft.Owin中定义了Owin相关的主体如上下文、管道Builder以及身份验证相关的业务逻辑AuthenticationManager。
2. Microsoft.Owin.Security作为Owin安全相关功能的补充,定义了身份验证的模式(积极和消极)以及用于身份验证的中间件和处理器基类。
3. Microsoft.Owin.Security.XXX类型作为真实的身份验证逻辑实现者提供了各种不同的基于Cookie的、Token的甚至第三方账户等的身份验证逻辑。
4. Microsoft.AspNet.Identity.Owin有两个主要对象,SignInManager封装了登录时的业务逻辑,这个业务逻辑既包括了用户数据的操作(UserManager)和身份验证的逻辑,提供了普通登录、双因子登录、外部账户登录等高级功能,而AuthenticationManagerExtensions同样也是针对这些高级功能对AuthenticationManager的拓展。
AuthenticationManager作为Owin中身份验证的业务的核心,其接口定义如下: