本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址  www.cnblogs.com/tdws

相信了解了MS Identity认证体系的一定知道UserManager的作用,他是整个体系中的调度者,他定义了一套用户行为来帮助我们管理用户信息,角色信息,处理密码等。而其实现则在UserStore当中,我们可以实现其为我们定义的比如IUserStore,IUserPasswordStore,IRoleStore等等. 我们可以基于一整套用户行为,自定义自己的用户信息和数据结构以及数据存储。那么关于Password的Hasher,MS依然为我们提供了完整的行为定义,也由UserManager来调度。比如

 UserManager.PasswordHasher.HashPassword(password)
PasswordHasher在UserManager接口中是这样定义的:

我原本对其默认实现是没有兴趣的,出于独立多个应用的登陆认证的目的,所以需要一个独立的用户认证项目来作为认证服务,其仅生产token,认证成功后,用户的HTTP Request Header的Authorization带着 token来访问应用服务器上的各种资源。

就是因为这样的原因,在多个应用的密码认证上出现了这样一个问题:

比如应用A采用了实现IPasswordHasher来自定义加密方式——MD5+salt的形式,而应用B则采用了Identity默认的PasswordHasher来实现,通过反编译得到如下代码:

所以为了兼容多个应用不同的加密方式,我不得不反编译出源码,拿到其默认加密方式,根据不同应用名称,来判断对密码加密或者解密,或者直接通过某种方式来对比数据库和用户输入的密码。先上MS默认的PasswordHasher具体实现

 // Decompiled with JetBrains decompiler
// Type: Microsoft.AspNet.Identity.Crypto
// Assembly: Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: E3A10FFD-023A-4BC3-AD53-32D145ABF1C9
// Assembly location: C:\Sport\NewProject\V2.0\Api\Fantasy.Sport\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography; namespace Microsoft.AspNet.Identity
{
internal static class Crypto
{
private const int PBKDF2IterCount = ;
private const int PBKDF2SubkeyLength = ;
private const int SaltSize = ; public static string HashPassword(string password)
{
if (password == null)
throw new ArgumentNullException("password");
byte[] salt;
byte[] bytes;
using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, , ))
{
salt = rfc2898DeriveBytes.Salt;
bytes = rfc2898DeriveBytes.GetBytes();
}
byte[] inArray = new byte[];
Buffer.BlockCopy((Array) salt, , (Array) inArray, , );
Buffer.BlockCopy((Array) bytes, , (Array) inArray, , );
return Convert.ToBase64String(inArray);
} public static bool VerifyHashedPassword(string hashedPassword, string password)
{
if (hashedPassword == null)
return false;
if (password == null)
throw new ArgumentNullException("password");
byte[] numArray = Convert.FromBase64String(hashedPassword);
if (numArray.Length != || (int) numArray[] != )
return false;
byte[] salt = new byte[];
Buffer.BlockCopy((Array) numArray, , (Array) salt, , );
byte[] a = new byte[];
Buffer.BlockCopy((Array) numArray, , (Array) a, , );
byte[] bytes;
using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, ))
bytes = rfc2898DeriveBytes.GetBytes();
return Crypto.ByteArraysEqual(a, bytes);
} [MethodImpl(MethodImplOptions.NoOptimization)]
private static bool ByteArraysEqual(byte[] a, byte[] b)
{
if (object.ReferenceEquals((object) a, (object) b))
return true;
if (a == null || b == null || a.Length != b.Length)
return false;
bool flag = true;
for (int index = ; index < a.Length; ++index)
flag &= (int) a[index] == (int) b[index];
return flag;
}
}
}

有人可能会问,拿到了这些源码要如何应用呢。下面就是浅述到这个问题。

一开始我天真的认为,不就是一个加密么,不用仔细看了,拿来用就好了?

在注册用户和修改密码的时候,都是通过上面 HashPassword 方法来做的密码加密,那我在新的自定义PasswordHasher中,为应用B对比用户登录密码的时候,把用户输入直接通过HashPassword加密一边不就好了?所以我自定义的VerifyHashedPassword (Verify译为核实)方法,就是比较数据库中的Pwd和经过hasher处理的结果是否相等。 可结果是,每次相同的字符串,会产生不同的加密结果,和以前玩md5+salt不一样呀。所以我又想到了其默认实现的  VerifyHashedPassword 方法。

所以最后要说的就是 你可以拿来微软Identity的加密方式(上面的Hasher)直接使用 , 在比较用户输入和数据库中已经经过hash的存储结果进行对比的时候,使用其 VerifyHashedPassword()方法。即使不使用Identity认证 也可以用此加密算法。

如果需要更多了解Identity和OWIN,请看腾飞的如下四篇文章:

http://www.cnblogs.com/jesse2013/category/551550.html

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下加推荐按钮。
如果,您希望更容易地发现我的新博客,不妨点击下方红色【关注】的。
因为,我的分享热情也离不开您的肯定支持。

感谢您的阅读,我将持续输出分享,我是蜗牛, 保持学习,谨记谦虚。不端不装,有趣有梦。

Microsoft.Identity的IPasswordHasher的默认实现与运用的更多相关文章

  1. Microsoft.Identity的IPasswordHasher加密的默认实现与运用

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址  www.cnblogs.com/tdws 相信了解了MS Identity认证体系的一定知道UserManager的作用,他是整个体 ...

  2. MVC6 OWin Microsoft Identity 自定义验证

    1. Startup.cs中修改默认的验证设置 //app.UseIdentity(); app.UseCookieAuthentication(options => { //options.A ...

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

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

  4. Microsoft Orleans 之 入门指南

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...

  5. Microsoft Orleans构建高并发、分布式的大型应用程序框架

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...

  6. 任务44:Identity MVC: EF + Identity实现

    使用VSCode开发 Razer的智能感知不好.所以这里切换为VS2017进行开发: 新建一个Data的文件夹来存放我们的DBContext.在Data文件夹下新建: ApplicationDbCon ...

  7. 2019-1-29-win10-uwp-使用-Microsoft.Graph-发送邮件

    title author date CreateTime categories win10 uwp 使用 Microsoft.Graph 发送邮件 lindexi 2019-01-29 16:36:3 ...

  8. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  9. asp.net core 3.x Identity

    一.前言 这方面的资料很多,重复的写没必要,但是最近一直在学习身份验证和授权相关东东,为了成体系还是写一篇,主要是从概念上理解identity系统. 参考:https://www.cnblogs.co ...

随机推荐

  1. Laravel 目录结构分析

    根目录结构 /app/bootstrap/public/vendorartisancomposer.jsonserver.php 1./app 整个Laravel 目录中最需要我们注意的地方,包含设置 ...

  2. (中等) POJ 1436 Horizontally Visible Segments , 线段树+区间更新。

    Description There is a number of disjoint vertical line segments in the plane. We say that two segme ...

  3. memcache和memcached之间的区别和联系

    memcache和memcached区别: Memcache是什么?Memcache是一个自由和开放源代码.高性能.分配的内存对象缓存系统.用于加速动态web应用程序,减轻数据库负载.它可以应对任意多 ...

  4. Linux之文件权限属性设置

    文件权限属性设置 1.chown命令 chrep命令 chown命令改变某个文件或目录的所有者和所属的组,该命令可以向某个用户授权,使该用户变成指定文件的所有者或者改变文件所属的组. 用户可以是用户或 ...

  5. Git和Github的配合使用

    Git教程 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 Git 本地仓库详解  ...

  6. eclipse中集成svn maven开发手册---maven编译打包

    使用eclipse中maven进行打包. 打好的包在相应的workspace下面会有一个release的文件夹,如图

  7. iOS 程序测试、程序优化、提交前检测

    1. 数据显示如果是数值要考虑到0的情况 2. 数据变化对前一个页面及相关页面的影响,也即数据同步问题.如果是有其它设备改变数据,那数据请求就应该在willappear(视图将要显示事件)进行请求,以 ...

  8. winform - json串的转换

    通过java接口,或者查询数据库返回json串. 可以有两种方式进行解读. 1.简单方式 没有深层结构,最好只有一条数据(当然也可多条).可以用datatable来获取.返回的是clo0.clo1.c ...

  9. UVa 524 - Prime Ring Problem

    题目大意:输入正整数n,把整数1,2...,n组成一个环,使得相邻两个整数之和均为素数.输出时从整数1开始逆时针(题目中说的不是很明白??)排列.同一个环应恰好输出一次. 枚举,并在枚举每一个数是进行 ...

  10. centos 6 下编译安装 nginx

    下载nginx源码包,可以到nginx官方的下载文件归档里 http://nginx.org/download/ 下载 下载pcre源码,并编译安装,从pcre官方下载  ftp://ftp.csx. ...