详解ASP.NET中Identity的身份验证代码

本篇内容主要讲述了实现基于微软账户的第三方身份验证、实现双因子身份验证、 验证码机制这3个内容。

实现基于微软账户的第三方身份验证

在微软提供的ASP.NET MVC模板代码中,默认添加了微软、Google、twitter以及Facebook的账户登录代码(虽然被注释了),另外针对国内的一些社交账户提供了相应的组件,所有组件都可以通过Nuget包管理器安装:

从上图中看到有优酷、微信、QQ、微博等组件,其中一些是微软提供的,一些是其它开发者提供的。而本文将使用微软账户为例来介绍如何实现一个第三方登录。

注:本章主要代码参考ASP.NET MVC模板代码,所以在文章中只列出关键代码,其余代码与模板中的完全一致。

组件安装及Key申请

在开发之前首先需要通过Nuget安装Microsoft.Owin.Security.MicrosoftAccount:

  

另外就是需要去微软的开发者中心使用微软账户创建一个自己的应用信息https://apps.dev.microsoft.com/,并保存应用的ID以及密钥用于对身份验证中间件进行配置:

  

创建过程如下:

1. 点击添加应用按钮,进入应用程序注册页面,填写应用名称并点击Create按钮(注:由于我已经有一个名称为My Blog的App,所以下面的Test App的创建流程仅仅是用于演示,后续的身份验证实际上是使用之前创建的My Blog):

  

2. 在后续页面中点击生成新密码来生成密钥(注:该密码只显示一次,需要在弹出框中复制并保存下来):

  

3. 添加平台:点击添加平台按钮,添加一个Web平台,并在平台的重定向Url中填入本地调试的地址信息(注:一定需要启动HTTPS并且地址后需要添加signin-microsoft,VS可以在项目的属性中开启SSL,并设置SSL的URL):

  

4. 保存更改。

添加中间件

在上一篇文章中介绍了,第三方账户身份验证除了特定账户身份验证中间件外,还需要添加一个消极模式的外部Cookie身份验证中间件,所以首先需要在项目的Startup文件中添加一下代码:

  

然后再在该中间件后加入微软身份验证中间件(注:中间件顺序会影响处理流程,微软身份验证中间件必须在外部Cookie中间件后),并设置上面创建的应用ID及密钥:

  

添加Controller及页面的功能支持

现在可以说应用中已经支持微软的账户身份验证了,但是在应用中还未提供微软身份验证的入口,以及登陆后用户信息的补全等功能。

1. 在页面上添加验证入口,在Login页面上加入以下代码,通过AuthenticationManager来获取所有的第三方身份验证方式,并生成对应链接:

  

  

2. 在AccountController中添加ExternalLogin Action方法(注:该方法主要目的是调用AuthenticationManager的Challenge方法来触发微软身份验证中间件的ResponseChallenge方法来完成页面的跳转):

   

其中ChallengeResult是一个自定义的ASP.NET MVC Reuslt类型:

  

3. 加入第三方验证后的回调方法ExternalLoginCallback,该回调方法是获取第三方身份验证后的用户信息,然后在本地数据库中查找该用户,如果存在那么登录成功,否则需要对该用户信息进行补全。

  

4. 添加第三方账户信息补全页面及Action方法,其中action方法接收到补全的用户信息后完成用户注册功能,但要注意的是第三方账户没有密码,仅仅是在AspNetUserLogins表中添加了第三方验证的信息:

   

运行结果:

1.访问登录页面出现Microsoft的按钮(注:必须使用HTTPS地址才能正常的使用微软身份验证):

2. 点击微软身份验证按钮后,跳转到微软账户登录页面:

  

  

3. 完成登录后,由于是第一次登录,所以会跳转到信息补全页面:

  

输入邮箱后将登录成功:

  

数据库中的信息:

  

上图中可以看到无密码,然后在Login表中有一条数据:

实现双因子身份验证

Identity的双因子身份验证实际上是Identity的一个内置功能,为什么说是内置呢?因为只需要实现信息的发送(如邮件、短信等),然后再对Identity中的SignInManager进行简单的配置然后添加一些用于发送、填写验证码的页面就可以完成。所以首先需要完成的就是实现信息发送功能。

注:这里信息发送功能使用将信息写到硬盘的方式模拟。

1. 实现信息的发送:
在ASP.NET MVC默认的模板中就为我们创建了如下代码:

默认的邮件及短信发送器,只不过它没有实现,仅仅是返回了一个空值,现在使用写硬盘的方式将信息写到硬盘上:

  

2. 完成UserManager的双因子验证配置:

  

三个关键点:1. TokenProvider,它用来生成验证码。2. 信息格式。3. 信息发送服务。

3. 在身份验证管道中加入双因子验证中间件:

  

两个中间件前者用于处理二次验证,后者用于记住登录状态,下次访问系统时自动登录。

4. 添加验证码发送方式选择以及验证码填写页面及相应的Action方法(代码略)。

5. 在数据库中将演示用的用户信息改为启用二次验证(注:模板代码中有用于管理个人信息的功能,此处省略了实现,直接通过修改数据数据的方式开启用户的双因子验证、添加电话号码等):

6. 运行结果:

登录后需要选择验证码发送方式:

选择后点击提交按钮,页面调整到验证页面的同时,指定的文件中生成了需要的验证码:

  

  

填写验证码后点击提交按钮,则登录成功:

  

注:双因子验证也可以应用到第三方账户的登录方式上,双因子验证只与用户有关与身份验证方式无关。

验证码机制

对于双因子验证来说,它实际上就是在普通验证或第三方账户验证的基础上增加了验证码的发送和验证两个环节,那么对于验证码这个主体Identity是如何来维护的呢?

在上面的介绍中,有一个环节就是需要通过对UserManager进行配置以支持双因子验证的消息发送、消息生成等等:

  

根据这个代码看来XXXTokenProvider是专门用来维护验证码的,而XXXService是用来发送的,所以这里将对TokenProvider进行说明,了解验证码是如何维护的:

上图是TokenProvider相关的一个简单类图,从类图中可以看出TokenProvider实际上是实现了一个名为IUserTokenProvider的接口,该接口中有4个方法,它们的作用分别是:

  ● GenerateAsync:根据UserManager以及User信息来生成一个令牌(Token)。

  ● IsValidProviderForUserAsync:判断这个Token提供器对这个用户是否是有效的(如果使用短信验证,但是该用户没有设置手机号,那么就是无效的)。

  ● NotifyAsync:当Token生成后调用该方法通知用户,如短信或邮件通知。

  ● ValidateAsync:用于验证Token是否有效。

而TotpSecutityStampBasedTokenProvider是一个实现了IUserTokenProvider接口的,通过用户安全戳生成验证码的生成器:

从代码中可以看到该算法是基于rfc6238(TOTP: Time-Based One-Time Password Algorithm,基于时间的一次性密码算法) https://tools.ietf.org/html/rfc6238,然后通过用户的安全戳以及GetUserModifierAsync方法生成特定的信息熵来完成密码加密,关于信息熵可参考:https://www.zhihu.com/question/22178202,上面将生成后的令牌执行ToString("D6")是将其转换为一个6位数字的字符串。

而Token的验证方式和生成差不多都是通过用户安全戳和信息熵来验证提交的验证码(它实际上是一种hash算法):

以上已经解释了最初验证码的生成和验证的问题,所以对于EmailTokenProvider和PhoneNumberTokenProvider只是对熵的生成、对Provider的有效性(是否存在Email或电话号码)、通知方式进行了修改,下面是PhoneNumberTokenProvider相关代码:

小结  

本章主要是使用代码的形式实现了ASP.NET中的第三方验证和双因子验证,文中的代码都来自ASP.NET MVC的模板,所以文中仅仅是对关键的代码进行了介绍,一些细节的内容可参考完整代码。其中第三方验证使用的是微软账户,如果有环境支持可以尝试国内的微信、QQ等身份验证。

另外在文章最后对验证码的生成和校验代码进行了分析,知道了它是基于Hash算法的信息加密、验证的机制来实现的。
ASP.NET MVC基于Identity提供了非常完善、强大的用户管理和身份验证功能,除了以上介绍的以外还有账户锁定、注册邮箱或短信验证功能,基本上已经涵盖了现在开发常用的功能,但这些功能被一个模板实现了,所以ASP.NET强大吗?

(0)

相关推荐

  • 详解ASP.NET中Identity的身份验证代码

    本篇内容主要讲述了实现基于微软账户的第三方身份验证.实现双因子身份验证. 验证码机制这3个内容. 实现基于微软账户的第三方身份验证 在微软提供的ASP.NET MVC模板代码中,默认添加了微软.Google.twitter以及Facebook的账户登录代码(虽然被注释了),另外针对国内的一些社交账户提供了相应的组件,所有组件都可以通过Nuget包管理器安装: 从上图中看到有优酷.微信.QQ.微博等组件,其中一些是微软提供的,一些是其它开发者提供的.而本文将使用微软账户为例来介绍如何实现一个第三方

  • 详解ASP.NET中Session的用法

    当用户在应用程序的页之间跳转时,存储在 Session 对象中的变量不会清除,而用户在应用程序中访问页面时,这些变量始终存在.当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象.当会话过期或被放弃后,服务器将终止该会话. 通过向客户程序发送唯一的 Cookie 可以管理服务器上的 Session 对象.当用户第一次请求 ASP 应用程序中的某个页面时,ASP 要检查 HTTP 头信息,查看是否有在报文中有名为 ASPSESSION

  • 详解ASP.NET MVC Form表单验证

    一.前言 关于表单验证,已经有不少的文章,相信Web开发人员也都基本写过,最近在一个个人项目中刚好用到,在这里与大家分享一下.本来想从用户注册开始写起,但发现东西比较多,涉及到界面.前端验证.前端加密.后台解密.用户密码Hash.权限验证等等,文章写起来可能会很长,所以这里主要介绍的是登录验证和权限控制部分,有兴趣的朋友欢迎一起交流. 一般验证方式有Windows验证和表单验证,web项目用得更多的是表单验证.原理很简单,简单地说就是利用浏览器的cookie,将验证令牌存储在客户端浏览器上,co

  • asp.net中的窗体身份验证(最简单篇)

    在创建网站中,常常会使用到身份验证.asp.net中内置了几种身份验证的方式,如Windows.Froms.Passport等.这几种身份验证的方式各有不同.一般来说,网站的身份验证方式都会经过以下几个步骤: 1.输入用户名和密码,单击确定按钮. 2.在后台判断用户名和密码是否正确,如果错误返回提示:如果正确,进入可访问的页面. 在ASP时代,通常都会在验证用户名和密码是否匹配之后,创建一个Session,然后在每个需要验证的页面中判断Session是否存在,如果存在,则显示页面内容:如果不存在

  • 详解Spring Security中的HttpBasic登录验证模式

    一.HttpBasic模式的应用场景 HttpBasic登录验证模式是Spring Security实现登录验证最简单的一种方式,也可以说是最简陋的一种方式.它的目的并不是保障登录验证的绝对安全,而是提供一种"防君子不防小人"的登录验证. 就好像是我小时候写日记,都买一个带小锁头的日记本,实际上这个小锁头有什么用呢?如果真正想看的人用一根钉子都能撬开.它的作用就是:某天你的父母想偷看你的日记,拿出来一看还带把锁,那就算了吧,怪麻烦的. 举一个我使用HttpBasic模式的进行登录验证的

  • 详解ASP.NET中加密和解密的方法

    散列运算 mscorlib.dll下的System.Security.Cryptography下: 抽象类HashAlgorithm 抽象类MD5 MD5CryptoServiceProvider SHA1 SHA1CryptoServiceProvider密封类:调用Windows Crypto API SHA1Managed普通类:用托管代码写的 SHA256 SHA256CryptoServiceProvider SHA256Managed SHA384 SHA512 对字节数组或流散列运

  • 详解ASP.NET Core中配置监听URLs的五种方式

    默认情况下,ASP. NET Core应用会监听一下2个Url: http://localhost:5000 https://localhost:5001 在本篇博文中,我将展示如何使用五种不同的方式改变应用监听的URLs. 在ASP.NET Core项目启动时,有多种配置监听Url的方式,在我之前的一篇博客中,已经展示了在ASP.NET Core 1.0中如何应用不同的方式配置,在ASP.NET Core 3.x中,大部分方式还是一样的. UseUrls() - 在Program.cs配置程序

  • 详解Asp.net 5中的ApplicationBuilder

    ApplicationBuilder(IApplicationBuilder接口),是OWIN的基础,而且里面都是代理.代理的代理,各种lambda表达式,估计要看这部分代码,很多人得头昏脑涨.今天就对个类以及几个扩展方法进行讲解. 按惯例先贴代码(这是我修改后的,将接口继承去掉了.HttpContext类修改成自己的MyHttpContext类) public class ApplicationBuilder { private readonly IList<Func<RequestDele

  • asp.core 同时兼容JWT身份验证和Cookies 身份验证两种模式(示例详解)

    在实际使用中,可能会遇到,aspi接口验证和view页面的登录验证情况.asp.core 同样支持两种兼容. 首先在startup.cs 启用身份验证. var secrityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"])); services.AddSingleton(secrityKey); services.AddAuthentication(CookieAut

  • 详解Angular开发中的登陆与身份验证

    前言 由于 Angular 是单页应用,会在一开始,就把大部分的资源加载到浏览器中,所以就更需要注意验证的时机,并保证只有通过了验证的用户才能看到对应的界面. 本篇文章中的身份验证,指的是如何确定用户是否已经登陆,并确保在每次与服务器的通信中,都能够满足服务器的验证需求.注意,并不包括对具体是否具有某一个权限的判断. 对于登陆,主要是接受用户的用户名密码输入,提交到服务器进行验证,处理验证响应,在浏览器端构建身份验证数据. 实现身份验证的两种方式 目前,实现身份验证的方法,主要有两个大类: Co

随机推荐