初识Identity(一)

时间:2023-03-09 13:21:33
初识Identity(一)

一、Authentication(身份验证)和Authorization(授权)

如何构建安全的web应用?authentication和authorization是asp.net中最重要最基本的防护原则。

Authentication(验证):鉴定应用程序访问者身份的过程。

Authorization(授权):判断访问者应该拥有何种级别的访问安全资源的权限。

初识Identity(一)

二、asp.net中身份验证方式

windows验证和表单验证(Forms Authentication)就是ASP.NET中两种主要的安全机制。

Windows验证:一般用于局域网应用。使用Windows验证时,用户的Windows安全令牌在用户访问整个网站期间使用HTTP请求,进行消息发送。应用程序会使用这个令牌在本地(或者域)里验证用户账号的有效性,也会评估用户所在角色所具备的权限。当用户验证失败或者未授权时,浏览器就会定向到特定的页面让用户输入自己的安全凭证(用户名和密码)。

Forms验证:Windows验证的局限性非常明显,一旦用户有超出本地域控制器范围的外网用户访问网站,就会出现问题。ASP.NET表单验证(Forms Authentication)很好的弥补了这一缺陷。使用表单验证,ASP.NET需要验证加密的HTTP cookie或者查询字符串来识别用户的所有请求。cookie与ASP.NET会话机制(session)的关系密切,在会话超时或者用户关闭浏览器之后,会话和cookie就会失效,用户需要重新登录网站建立新的会话。

初识Identity(一)

第一步 在页面登录框输入账号和密码。

第二步 检查用户是否有效。可以从配置文件、SQL Server数据库或者其他外部数据源中查找。

第三步 如果用户有效,则在客户端生成一个cookie文件。cookie文件标识用户已经验证通过,当你访问网站其他资源时,不需要重新验证。

虽然使用表单认证能解决基本的身份验证问题,但大部分应用程序还包含角色和用户管理以及权限信息的存储问题。因此,我们不得不做下面这些事情:

  • 创建用户和角色表。
  • 编写访问数据表的代码。
  • 提供用户和密码验证的方法。

三、认识ASP.NET Membership

因为表单认证需要重复处理角色和用户管理以及权限信息的存储问题,ASP.NET 2.0中引入了Membership的重磅级技术方案。ASP.NET Membership很好的解决了WEB应用程序在成员资格方面的常见需求,这些需求包括表单身份验证,存储用户名、密码和用户资料信息 (profile)等。Membership极大地简化了应用程序的编写,但Membership在使用中也有自身难以克服的问题:

  • 数据库架构受限于SQL Server。对其他数据库很难兼容。
  • 生硬的表存储结构。如果需要添加额外的用户资料信息,需要存储在其他表,使得这些信息难以访问(除非通过 Profile Provider API)。

  • 系统仅依据关系数据库设计。当然,你也可以写一个面向非关系型数据库的Provider(例如 Windows Azure 存储表),但是不得不写大量的代码,来解决兼容问题。

  • 不能使用OWIN。由于登录、注销功能基于表单认证,第三方账号的接入显得比较困难。(初步了解Owin

四、ASP.NET Identity的推出

鉴于ASP.NET Membership的弊端,微软又开发一套新的安全框架ASP.NET Identity。ASP.NET Identity具有以下优势:

1.统一的框架

可以轻松地整合到 ASP.NET 各种框架以及程序上。例如,ASP.NET MVC, Web Forms, Web Pages, Web API 和 SignalR等。

2.自定义用户信息

可以很方便的扩展用户信息。比如,添加用户的生日,年龄等。
3.灵活的角色管理
ASP.NET Identity 中的角色提供程序让你可以基于角色来限制对应用程序某个部分的访问。你可以很容易地创建诸如 “Admin” 之类的角色,并将用户加入其中。

4.数据持久性以及兼容性

默认情况下,ASP.NET Identity 系统将所有的数据存储在SQL Server数据库中,并且使用 Entity Framework Code First 实现数据库的管理。当然,对其他存储介质也有很好的支持。例如 SharePoint, Windows Azure 存储表服务, NoSQL 数据库等等。

5.单元测试能力

ASP.NET Identity 使得 Web 应用程序能够更好地进行单元测试。

6.OWIN 集成

ASP.NET 验证(Authentication)基于 OWIN 中间件,可以在任何 OWIN 的宿主上使用。ASP.NET Identity 不依赖于System.Web,完全兼容 OWIN 框架,可以被用在任何由OWIN 承载的应用程序。

7.NuGet 包

ASP.NET Identity 作为一个 NuGet 包进行发布,并且在 Visual Studio 2013 中作为 ASP.NET MVC, Web Forms 和 Web API 项目模板的一部分提供。你也可以从 NuGet 库中下载到该 NuGet 包。

初识Identity(一)

ASP.NET Identity基本功能

初识Identity(一)

ASP.NET Identity基本组成部分

ASP.NET Identity主要包括核心功能模块、EntityFramework模块以及OWIN模块。具体如下:

Microsoft.AspNet.Identity.Core 

  核心库,包含Identity的主要功能。

Microsoft.AspNet.Identity.EntityFramework
  主要包括ASP.NET Identity 的EF 部分的实现。

Microsoft.AspNet.Identity.OWIN
  ASP.NET Identity对OWIN 的支持。

参考:MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN

ASP.NET Identity主要提供的功能是帮助我们管理用户,角色等信息,它主要负责的是存储这一块,也就是我们的信息存到哪里去的问题。

通过代码我们可以发现实现登录实际上只有简单的三行代码:

private IAuthenticationManager AuthenticationManager
{
get { return HttpContext.GetOwinContext().Authentication; }
} private async Task SignInAsync()
{
// 1. 利用ASP.NET Identity获取用户对象
var user = await UserManager.FindAsync("UserName", "Password");
// 2. 利用ASP.NET Identity获取identity 对象
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
// 3. 将上面拿到的identity对象登录
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);
}

我们发现UserManager.CreateIdentityAsync返回给我们的对象是一个ClaimsIdentity,这又是一个什么玩意?它和我们原来所熟知的Identity对象有什么关联么?毕竟长的那么像,在深入之前,我们先要了解一下下面的概念。

什么是Claims-based(基于声明)的认证

  首先这个玩意不是微软特有的,Claims-based认证和授权在国外被广泛使用,包括微软的ADFS,Google,Facebook等。 国内我就不知道了,没有使用过国内的第三方登录,有集成过QQ登录或者支付宝登录的同学可以解释一下。

Claims-based认证主要解决的问题?

  对比我们传统的Windows认证和Forms认证,claims-based认证这种方式将认证和授权与登录代码分开,将认证和授权拆分成另外的web服务。活生生的例子就是我们的qq集成登录,未必qq集成登录采用的是claims-based认证这种模式,但是这种场景,千真万确就非常适合claims-based认证。

  Claims-based认证的主要特点:

  • 将认证与授权拆分成独立的服务
  • 服务调用者(一般是网站),不需要关注你如何去认证,你用Windows认证也好,用令牌手机短信也好,与我无关。
  • 如果用户成功登录的话,认证服务(假如是QQ) 会返回给我们一个令牌。
  • 令牌当中包含了服务调用者所需要的信息,用户名,以及角色信息等等。

  总的来说就是,我再也不用管你怎么登录,怎么样去拿你有哪些角色了,我只需要把你跳到那个登录站点上,然后它返回给我令牌信息,我从令牌上获取需要的信息来确定你是谁,你拥有什么角色就可以了。 

进一步理解Claims-based 认证

  为了让大家进一步理解Claims-based认证,我们从一个普通的登录场景开始说起,拿QQ集成登录来举例。

  1. 用户跑到我们的网站来访问一个需要登录的页面
  2. 我们的网站检测到用户没有登录,返回一个跳转到QQ登录页的响应(302 指向QQ登录页面的地址并加上一个返回的链接页面,通常是returnUrl=)
  3. 用户被跳转到指定QQ的登录页面
  4. 用户在QQ登录页面上输入用户名和密码,QQ会到自己的数据库中查询,一旦登录成功,会返回一个跳转到我们站点的响应(302指向我们的网站页面)
  5. 用户被跳转到我们网站的一个检测登录的页面,我们可以拿到用户的身份信息,建立ClaimsPrinpical和ClaimsIdentity对象,生成cookie等。
  6. 我们再把用户带到指定的页面,也就是returnUrl,那是用户登录前最后一次访问的页面

以qq为例:

初识Identity(一)

简单的来说,就是把登录的代码(验证用户,获取用户信息)拆分成独立的服务或组件。