前面的文章中为My Blog加入了文章的管理功能(ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块),但是管理功能应该只能由“作者”来访问,那么要如何控制用户的访问权限?也就是当用户访问管理功能时需要对用户进行身份验证,对于用户来说身份验证也就是登录,即提供一个登录界面,通过账号密码的形式登录后就可以访问受限制的内容。

  本文将从以下几个方面介绍ASP.NET MVC是如何实现用户身份验证的:
  ● Web中的身份验证
  ● ASP.NET的Identity组件介绍
  ● ASP.NET MVC中使用Identity——组件安装
  ● ASP.NET MVC中使用Identity——EntityFramework
  ● ASP.NET MVC中使用Identity——注册功能的实现
  ● ASP.NET MVC中使用Identity——登录功能的实现
  ● ASP.NET MVC中使用Identity——身份验证功能的实现

  注:本文的目的是介绍在已存在的项目中如何使用Identity组件来添加用户注册、登录和验证的功能,所以内容会比较细琐,后续会对Identity中比较关键的点进行介绍,如用户密码的加解密、Cookie的生成与验证,Identity与Owin等等方面进行深入分析介绍。

Web中的身份验证

  Web应用作为一种特殊的应用软件系统,它是基于HTTP协议的,由于HTTP的独特性(无状态)所以每一次访问都是独立的、不携带上一次请求信息的,所以现在常用的身份验证方式都是通过Cookie或者url查询字符串的形式来保存“状态”信息,达到每次访问服务器,服务器都能“知道”用户身份的目的。

  ASP.NET作为一个Web程序的开发框架,提供了一些身份验证的方式如From验证,它通过用户提到的服务器的用户特征(如用户名、密码等)生成一个加密的Cookie信息,后续请求中将带着该Cookie信息证明用户身份。下图是博客园中的Cookie信息:

  

  随着软件系统的发展,普通的身份验证已经不能满足系统的需求,如登录时候的二次验证、第三方账号登录、用户授权等。所以ASP.NET又针对这些需求开发了Identity组件(Identity的前身为MemberShip)。

ASP.NET的Identity组件介绍

  Identity用来快速为ASP.NET应用程序搭建一个完善的身份验证系统。它可以支持ASP.NET框架下的所有程序身份验证,并通过EF Code First来支持用户数据的持久化,并集成OWIN来解耦不再依赖System.Web。另外它还支持第三方账号登录、短信/邮件二次验证等高级功能。

  Identity主要的组件如下:

  ● Microsoft.AspNet.Identity.Core:Identity的核心类库,实现了身份验证的核心功能,并提供了拓展接口。
  ● Microsoft.AspNet.Identity.EntityFramework:Identity数据持久化的EF实现。
  ● Microsoft.AspNet.Identity.OWIN:基于Identity的OWIN身份验证插件,它代替了原有的Form验证。
  ● Microsoft.Owin.Host.SystemWeb:Owin的IIS宿主,将IIS的接收到的请求转入Owin处理。

ASP.NET MVC中使用Identity——组件安装

  1. 通过Nuget来安装Microsoft.AspNet.Identity.EntityFramework(已包含Microsoft.AspNet.Identity.Core):

  

  2. 安装Microsoft.AspNet.Identity.OWIN:

  

  3. 安装Microsoft.Owin.Host.SystemWeb:

  

ASP.NET MVC中使用Identity——EntityFramework

  上面介绍过Identity支持EF的code first,那么自然就会想到实体与DBContext,那么在Identity中它们是怎么实现的呢?

  1. Identity中的实体:

  以User信息为例,Microsoft.AspNet.Identity.Core类库中提供了User的核心接口:

  

  它的具体实现则位于Microsoft.AspNet.Identity.EntityFramework中:

  

  除了User外,Identity还定义了Role、UserClaim、UserLogin以及UserRole这些实体,如下图:

  

  2. Identity中的DBContext:

  在Microsoft.AspNet.Identity.EntityFramework中提供了一个IdentityDbContext类型(注:其它IdentityDbContext的泛型实现是用于对实体进行拓展的,如果没有拓展需求,那么使用非泛型类型即可)。

  

  3. 在ASP.NET MVC项目中使用Identity提供的DbContext(注:本例中的代码大部分参考ASP.NET MVC默认模板代码):

    1). 继承IdentityDbContext<TUser>类型,实现自己的DbContext(注:通过继承来使用Identity的DbContext可以灵活的根据需求来改变DbContext及其实体的配置)。

    

    2). 使用enable-migrations命令启用自动迁移,并在BlogIdentityDbContext中设置自动将数据库更新至模型最新版本:

    自动迁移(即无需使用add-migration命令来添加数据库结构变更):

    

    自动将数据库更新到模型最新版本:

    

    注:本例基于My Blog的MySQL数据库实现,在更新数据库时为避免一下错误,所以在OnModelCreating中加入了两个对象的主键。

    

    3). 在web.config中加入MySQL的EF配置以及一个名称为"DefaultConnection"的连接字符串(因为上面的DbContext构造方法中指定了参数DefaultConnection):

    

     连接字符串:与BlogContext共用同一个数据库:

     

    注:此处要说明两点,第一是使用配置文件的形式来配置EF的MySQL配置原因是,MyBlog中没有引用EF MySQL的组件,无法使用代码,只有等编译完成后把所有依赖的程序集复制到bin目录下,启动程序时通过配置文件解析。第二点是现在在整个解决方案中引入了两个DBContext,多个DBContext是可以共存的,只要对其进行正确的配置并提供正确的连接字符串。如果一个项目中有多个DBContext时,对其进行迁移操作就需要通过参数指定被操作的DbContext,可以参考这篇文章:http://www.cnblogs.com/Jack-Blog/p/4699596.html

    4). 可以执行update-database命令将DbContext同步到数据库中(因为设置了数据库自动同步,所以也可以等待后面运行程序时自动同步):

    

    

ASP.NET MVC中使用Identity——注册功能的实现

  在ASP.NET MVC中实现注册功能之前,先要了解一下Identity组件提供的业务逻辑“层”(注:这里说“层”仅仅是为了对应现有的项目结构,有数据层和逻辑层,其实在Identity中也是这样划分的,虽然它们都在同一个程序集中)。

  Identity中提供了RoleManager、UserManager等业务逻辑的实现类型,下图是UserManager的定义:

  

  从图中可以看出,它已经具有创建用户、添加角色等逻辑的实现,所以对于注册功能来说仅需要调用UserManager的对应方法即可。下面就介绍如何添加注册功能:

  1. 添加注册使用的ViewModel:

  

  2. 创建AccountController以及Register Action方法:

  

  注:UserManager依赖UserStore,UserStore又依赖于DbContext,也就是说业务逻辑依赖仓储,仓储又依赖数据库操作的实现。

  3. 创建View:

  

  4. 在布局页面中加入注册链接:

  

  5. 运行:

  

  

  数据库结果:

  

ASP.NET MVC中使用Identity——登录功能的实现

  登录功能的目的是对用户提交到服务器的用户名和密码进行验证,验证成功后生成一个包含用户信息的加密的字符串并以Cookie的形式返回到客户端。

  登录功能的实现方法与注册差不多就是添加视图模型、Action和View,然后在Action中调用Identity的用户验证方法即可:

  1. 创建ViewModel:

  

  2. 添加登录Action(注:sigInManager封装了登录的业务逻辑包括写Cookie):

  

  3. 添加View并在布局页面加入登录链接:

  

  

  4. 运行效果:

  

  

  注:现在还未添加访问的限制,所以登录与不登录其实上是一样的。

ASP.NET MVC中使用Identity——身份验证功能的实现

  用户完成登录操作后仅仅是在Cookie中多了一个用户信息,如果不对该信息进行验证那么这个信息是没有作用的,ASP.NET中没有魔法,它任何的操作都是有代码在后面支撑,那用于支撑Identity的身份验证的代码是什么呢?之前在介绍Identity时提到过它是通过Owin来与Web服务器解耦的,Owin它是Web服务器处理HTTP请求的一个规范,而它在IIS中是一个httpModule扩展(关于Owin后续会进行详细介绍)。总的来说在IIS中Owin以HttpModule的拓展方式,为HTTP的请求处理又添加了一个处理管道。

  那么Identity与Owin的集成实际上是在Owin的处理管道中,来读取请求数据中的登录后生成的Cookie并验证,实现的具体方式如下:

  1. 创建一个Owin Startup类文件:

  

  2. 在Configuration方法中添加Cookie验证的中间件,当未登录访问受限内容时自动跳转登录页面:

  

  3. 为需要限制访问的Controller添加Authorize特性:

  

  4. 在布局文件中添加逻辑判断,当登录成功后显示用户名,未登录时显示登录链接:

  

  5. 运行:

  访问受限页面admin/home/index(未登录将跳转):

  

  登录后能够访问被限制的内容:

  

  登录后的首页(由于样式问题”欢迎 admin“字符串与背景同色( ╯□╰ )):

  

小结

  本章主要内容是对ASP.NET 身份验证以及Identity进行了简要的介绍,然后解释了在ASP.NET MVC中是如何通过Identity实现用户的注册、登录和身份验证的。本例的代码主要参考并简化了默认的ASP.NET MVC带有独立身份验证的模板代码,所以如有需要可对照模板代码进行对比。

  另外要注意的是通过模板建立的注册、登录都是带有模型数据验证的,但本例中没有加入,关于模型的验证会在后续介绍。

参考:

  http://johnatten.com/2014/04/20/asp-net-mvc-and-identity-2-0-understanding-the-basics/
  https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project
  https://msdn.microsoft.com/zh-cn/library/azure/ms789031(v=vs.90).aspx
  http://www.cnblogs.com/dinglang/archive/2012/06/03/2532664.html
  http://www.cnblogs.com/xzwblog/archive/2017/05/10/6834663.html

本文链接:http://www.cnblogs.com/selimsong/p/7723827.html

ASP.NET没有魔法——目录

ASP.NET没有魔法——ASP.NET 身份验证与Identity的更多相关文章

  1. ASP.NET没有魔法——ASP.NET Identity 的“多重”身份验证

    ASP.NET Identity除了提供基于Cookie的身份验证外,还提供了一些高级功能,如多次输入错误账户信息后会锁定用户禁止登录.集成第三方验证.账户的二次验证等,并且ASP.NET MVC的默 ...

  2. ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证

    随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...

  3. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  4. asp.net core 3.x 身份验证-3cookie身份验证原理

    概述 上两篇(asp.net core 3.x 身份验证-1涉及到的概念.asp.net core 3.x 身份验证-2启动阶段的配置)介绍了身份验证相关概念以及启动阶段的配置,本篇以cookie身份 ...

  5. ASP.NET没有魔法——ASP.NET Identity的加密与解密

    前面文章介绍了如何使用Identity在ASP.NET MVC中实现用户的注册.登录以及身份验证.这些功能都是与用户信息安全相关的功能,数据安全的重要性永远放在第一位.那么对于注册和登录功能来说要把密 ...

  6. ASP.NET没有魔法——ASP.NET MVC 过滤器(Filter)

    上一篇文章介绍了使用Authorize特性实现了ASP.NET MVC中针对Controller或者Action的授权功能,实际上这个特性是MVC功能的一部分,被称为过滤器(Filter),它是一种面 ...

  7. ASP.NET没有魔法——ASP.NET OAuth、jwt、OpenID Connect

    上一篇文章介绍了OAuth2.0以及如何使用.Net来实现基于OAuth的身份验证,本文是对上一篇文章的补充,主要是介绍OAuth与Jwt以及OpenID Connect之间的关系与区别. 本文主要内 ...

  8. ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)

    上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...

  9. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染

    对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的界面呈现工作是由浏览器完成的,Web应用的原理是通过Http协议从服务器上获取到 ...

随机推荐

  1. 201521123050 《Java程序设计》第14周学习总结

    1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 1.1立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) ...

  2. 201521123012 《Java程序设计》第十三周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec ...

  3. PHOTOSHOP常用快捷键大全

    PHOTOSHOP常用快捷键大全一.文件新建 CTRL+N打开 CTRL+O 打开为 ALT+CTRL+O关闭 CTRL+W保存 CTRL+S 另存为 CTRL+SHIFT+S另存为网页格式 CTRL ...

  4. Axios源码阅读笔记#1 默认配置项

    Promise based HTTP client for the browser and node.js 这是 Axios 的定义,Axios 是基于 Promise,用于HTTP客户端--浏览器和 ...

  5. [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

    关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...

  6. ②jquery复习

    # jQuery 复习--by 传智前端与移动开发学院 ## 1. jQuery是什么?(了解)+ www.github.com+ jQuery 其实就是一堆的js函数,是普通的js,只不过应用广泛, ...

  7. JAVA 一步一步向上爬

    Java分为基本数据类型和引用数据类型(类.接口.数组) Integer.MAX_VALUE 浮点型默认为double java采用Unicode char为两个字节 Unicode为每一个字符定制了 ...

  8. Painter's Problem poj1681 高斯消元法

    Painter's Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4420   Accepted: 2143 ...

  9. Linux系统centOS7在虚拟机下的安装及XShell软件的配置

    前面的话 本文将详细介绍Linux系统centOS7在虚拟机下的安装 准备工作 [系统下载] 在安装centOS7之前,首先在官网下载合适的版本 然后,选择一个链接下载即可 [虚拟机配置] 接下来,需 ...

  10. 通过npm写一个cli命令行工具

    前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要 ...