Microsoft.AspNet.Identity 自定义使用现有的表—登录实现

Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现。Microsoft.AspNet.Identity.EntityFramework则是Microsoft.AspNet.Identity的数据提供实现。但是在使用此框架的时候存在一些问题,如果是全新的项目还可以使用它默认提供的表名,字段名等。但是如果是在一些老的数据库上应用这个框架就比较麻烦了。所以我们实现一个自己的Microsoft.AspNet.Identity.EntityFramework

首先我们只说登录,登录的入口代码是

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);

对应Owin框架中的代码为

public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{SignInStatus result;if (this.UserManager == null){result = SignInStatus.Failure;}else{TUser tUser = await this.UserManager.FindByNameAsync(userName).WithCurrentCulture<TUser>();if (tUser == null){result = SignInStatus.Failure;}else if (await this.UserManager.IsLockedOutAsync(tUser.Id).WithCurrentCulture<bool>()){result = SignInStatus.LockedOut;}else if (await this.UserManager.CheckPasswordAsync(tUser, password).WithCurrentCulture<bool>()){await this.UserManager.ResetAccessFailedCountAsync(tUser.Id).WithCurrentCulture<IdentityResult>();result = await this.SignInOrTwoFactor(tUser, isPersistent).WithCurrentCulture<SignInStatus>();}else{if (shouldLockout){await this.UserManager.AccessFailedAsync(tUser.Id).WithCurrentCulture<IdentityResult>();if (await this.UserManager.IsLockedOutAsync(tUser.Id).WithCurrentCulture<bool>()){result = SignInStatus.LockedOut;return result;}}result = SignInStatus.Failure;}}return result;
}

由此代码可大概知晓登录的流程是,当然还有登录失败的流程就先不实现了。需要实现也非常简单,根据Owin的源代码实现对应的接口即可.

1.FindByNameAsync 先根据登录名找到user对象,使用UserManager中的UserStroe所实现IUserStore的接口方法

2.IsLockedOutAsync 检查登录是否锁定,使用UserManager中的UserStroe所实现的IUserLockoutStore接口方法

3.CheckPasswordAsync 检查密码,使用UserManager中的UserStroe所实现的IUserPasswordStore接口方法

4.ResetAccessFailedCountAsync 登录成功,重置登录失败计数,使用UserManager中的UserStroe所实现的IUserLockoutStore接口方法

5.SignInOrTwoFactor 双重身份验证,使用UserManager中的UserStroe所实现的IUserTwoFactorStore接口方法

 

SignInManager是入口,需要用到UserManager,UserManager需要用到关键的UserStore,具体的框架的介绍可以参考园子里其他的文章,都讲的很好,并且很好的讲明了为何需要这么设计。

实现

已有资源,假如我们已经有了数据库,有了user表,有了id字段guid类型,有了loginid代表登录的用户名,也就是源代码中的username

第一步 先实现我们自己的SignInManager,继承自Microsoft.AspNet.Identity.Owin.SignInManager<TUser, TKey>

public class WXSignInManager : SignInManager<WXUser, Guid>{public WXSignInManager(UserManager<WXUser, Guid> userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager){}public static WXSignInManager Create(IdentityFactoryOptions<WXSignInManager> options, IOwinContext context){return new WXSignInManager(context.GetUserManager<WXUserManager>(), context.Authentication);}

我们的SignInManager代码中有一行context.GetUserManager<WXUserManager>(),所以继续实现我们的UserManager。

第二步 实现我们的自己的UserManager,继承自Microsoft.AspNet.Identity.UserManager<TUser, TKey>

public class WXUserManager : UserManager<WXUser, Guid>{public WXUserManager(IUserStore<WXUser, Guid> store) : base(store){}public static WXUserManager Create(IdentityFactoryOptions<WXUserManager> options, IOwinContext context){return new WXUserManager(new WXUserStore(context.Get<WXDBContexnt>())){PasswordHasher = new MyPasswordHasher()};}}

由之前Owin源代码可以知道重点代码都在UserStore中,接下来

第三步,实现我们自己的UserStore,分别实现接口

Microsoft.AspNet.Identity.IUserStore<TUser, in TKey>,//数据库访问相关接口

Microsoft.AspNet.Identity.IUserLockoutStore<TUser, in TKey>,//用户锁定,登录失败计数相关接口

Microsoft.AspNet.Identity.IUserPasswordStore<TUser, in TKey>,//用户密码相关接口

Microsoft.AspNet.Identity,IUserTwoFactorStore<TUser, in TKey>//双重身份验证相关接口

public class WXUserStore : IUserStore<WXUser, Guid>, IUserLockoutStore<WXUser, Guid>, IUserPasswordStore<WXUser, Guid>, IUserTwoFactorStore<WXUser, Guid>{public WXUserStore(WXDBContexnt dbContext){this.dbContext = dbContext;}WXDBContexnt dbContext;public async Task<WXUser> FindByIdAsync(Guid userId){var user = await dbContext.WXUser.FindAsync(userId);return user;}public async Task<WXUser> FindByNameAsync(string userName){return dbContext.WXUser.Where(p => p.LoginId == userName).FirstOrDefaultAsync();}public Task ResetAccessFailedCountAsync(WXUser user){return Task.FromResult(false);}public Task<bool> GetLockoutEnabledAsync(WXUser user){return Task.FromResult(false);}public Task<string> GetPasswordHashAsync(WXUser user){return Task.FromResult(user.LoginPWD);}public Task<bool> GetTwoFactorEnabledAsync(WXUser user){return Task.FromResult(false);}}

这里仅仅是完成一个超级简单的登录功能,所以无关的实现都删除了,需要注意的是p => p.LoginId == userName,原有数据库中登录名的字段是loginId。接口的意思可以查看文档即可,相信从方法的名字就能猜到具体的意思,人家设计的接口就是好<!_!>。

我这里使用的是EF作为数据提供源,当然你也可以使用自己的,只需要替换FindByIdAsync,FindByNameAsync方法中对应的实现,哪怕是在这些方面里面使用ado.net直接查询数据都是完全没有问题的。wxuser我继承了系统已经存在的user对象,然后强类型实现了IUser接口,因为我原系统对象已存在了username属性。而此处的wxuser.username属性是作为用户登录的账号意思存在的。所以我强类型实现。

public class WXUser : 系统已存在的user entity对象, IUser<Guid>{Guid IUser<Guid>.Id{get{return this.Id;}}string IUser<Guid>.UserName{get{return this.LoginId;}set{this.LoginId = value;}}}public class WXDBContexnt : DbContext{public WXDBContexnt(){}public static WXDBContexnt Create() { return new WXDBContexnt(); }public DbSet<WXUser> WXUser { get; set; }}

大致代码就是如此了,当然我们自己实现的UserStore对象还有很多方法没有实现,but我只是需要一个登录不是么,可以慢慢改造的嘛<!_!>

写到最后想到通过重写的方式估计也能实现,这是新建项目生成的默认代码,为什么不可以增加[Table("Users")],[Column("LoginId")],override达到效果呢。

[Table("Users")]public class ApplicationUser : IdentityUser{public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager){// 请注意,authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的相应项匹配var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);// 在此处添加自定义用户声明return userIdentity;}[Column("LoginId")]public override string UserName{get{return base.UserName;}set{base.UserName = value;}}}

PS:看过源代码了,标记方式针对表名不行,源代码中写死了table name。字段名可以通过标记方式重命名 --by 2016-10-24

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stl vector 函数_vector :: front()函数以及C ++ STL中的示例

stl vector 函数C vector :: front()函数 (C vector::front() function) vector::front() is a library function of "vector" header, it is used to access the first element from the vector, it returns a reference to the first element of the vector. vect…

SpringBoot 使用注解实现消息广播功能

背景在开发工作中&#xff0c;会遇到一种场景&#xff0c;做完某一件事情以后&#xff0c;需要广播一些消息或者通知&#xff0c;告诉其他的模块进行一些事件处理&#xff0c;一般来说&#xff0c;可以一个一个发送请求去通知&#xff0c;但是有一种更好的方式&#xff0c;那就…

【Matlab】模式识别——聚类算法集锦

文章目录0.聚类分析简介0.1.简单的聚类样本生成器1.静态聚类算法1.1.最近邻聚类算法1.1.1.算法原理1.1.2.参考代码1.1.3.参数选择及运行结果1.2.最大最小距离法1.2.1.算法原理1.2.2.参考代码1.2.3.参数选择及运行结果2.动态聚类算法2.1.C均值聚类算法2.1.1.算法原理2.1.2.参考代…

Ant 风格路径表达式

ANT通配符有三种&#xff1a; 通配符说明?匹配任何单字符*匹配0或者任意数量的字符**匹配0或者更多的目录例子&#xff1a; URL路径说明/app/*.x匹配(Matches)所有在app路径下的.x文件/app/p?ttern匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern/**/exam…

java string查找_查找输出程序(Java String类)

java string查找Program 1 程序1 public class iHelp{public static void main (String[] args){System.out.println("Google".charAt(3));}}Output 输出量 gExplanation 说明 String.charAt() is a library function of String class, it returns character from…

【MATLAB】混合粒子群算法原理、代码及详解

目录1.算法1.1.原理1.2.性能比较1.3.步骤2.代码2.1.源码及注释2.2.执行与效果1.算法 1.1.原理 \qquad建议没接触过粒子群算法的朋友先看较为基础的全局粒子群算法原理及介绍&#xff0c;以下博文链接有详细的讲解、代码及其应用举例&#xff1a; 【Simulink】粒子群算法&#…

MVC HtmlHelper用法大全

HtmlHelper用来在视图中呈现 HTML 控件。 以下列表显示了当前可用的一些 HTML 帮助器。 本主题演示所列出的带有星号 (*) 的帮助器。 ActionLink - 链接到操作方法。 BeginForm * - 标记窗体的开头并链接到呈现该窗体的操作方法。 CheckBox * - 呈现复选框。 DropDownList *…

基于 MyBatis 手撸一个分表插件

背景事情是酱紫的&#xff0c;上级leader负责记录信息的业务&#xff0c;每日预估数据量是15万左右&#xff0c;所以引入sharding-jdbc做分表。上级leader完成业务的开发后&#xff0c;走了一波自测&#xff0c;git push后&#xff0c;就忙其他的事情去了。项目的框架是SpringB…

密码学哈希函数_哈希函数在密码学中的应用

密码学哈希函数A Hash Function is a mathematical function that converts a numerical value into another compressed numeric value. The input value for the hash functions can be of arbitrary length, but the output text that it will produce will always be of fi…

C语言图形化界面——含图形、按钮、鼠标、进度条等部件制作(带详细代码、讲解及注释)

目录0.引言1.素材准备2.编程2.1.创建你的界面2.2.创建按钮2.3.鼠标操作2.3.1.单击特效2.3.2.光标感应2.3.3.进度条3.完整代码及效果0.引言 \qquad看了CSDN上很多关于C程序图形化界面的介绍&#xff0c;有的代码繁琐难解&#xff0c;不方便调试修改&#xff1b;有的不够详细。本…

C#学习笔记(十三):I/O操作

C#的IO操作主要是针对文件夹和文件的读取和写入操作&#xff0c;下面我们来学习一下相关操作的类。 获取文件信息 Directory和DirectoryInfo 两个类的功能基本相同&#xff0c;区别如下&#xff1a; 前者继承System.Object,后者继承抽象类FileSystemInfo&#xff1b;前者是静态…

工作几年了,原来我只用了数据校验的皮毛

今天介绍一下 Spring Boot 如何优雅的整合JSR-303进行参数校验&#xff0c;说到参数校验可能都用过&#xff0c;但是你真的会用吗&#xff1f;网上的教程很多&#xff0c;大多是简单的介绍。什么是 JSR-303&#xff1f;JSR-303 是 JAVA EE 6 中的一项子规范&#xff0c;叫做 Be…

scala 字符串转换数组_如何在Scala中将十六进制字符串转换为字节数组?

scala 字符串转换数组Hex String in Scala denotes value in hexadecimal number system i.e. base 16 number system. Scala中的十六进制字符串表示以十六进制数表示的值&#xff0c;即以16进制数表示的系统。 Example: 例&#xff1a; hexString "32AF1"Byte Ar…

【MATLAB】无人驾驶车辆的模型预测控制技术(精简讲解和代码)【运动学轨迹规划】

文章目录<font color#19C>0.友情链接<font color#19C>1.引言<font color#19C>2.预测模型<font color#19C>3.滚动优化<font color#08CF>3.1.线性化3.2.UrU_rUr​的求取<font color#08CF>3.3.离散化与序列化<font color#08CF>3.4.实现…

顶级Javaer,常用的 14 个类库

作者&#xff1a;小姐姐味道&#xff08;微信公众号ID&#xff1a;xjjdog&#xff09;昨天下载下来Java16尝尝鲜。一看&#xff0c;好家伙&#xff0c;足足有176MB大。即使把jmc和jvisualvm给搞了出去&#xff0c;依然还是这么大&#xff0c;真的是让人震惊不已。但即使JDK足够…

单层神经网络线性回归_单层神经网络| 使用Python的线性代数

单层神经网络线性回归A neural network is a powerful tool often utilized in Machine Learning because neural networks are fundamentally very mathematical. We will use our basics of Linear Algebra and NumPy to understand the foundation of Machine Learning usin…

用express、mongodb、nodejs开发简单的登陆

原文http://my.oschina.net/chenhao901007/blog/312367 npm i -g express serve-favicon morgan cookie-parser body-parser kerberos mongoose(注意:kerberos不安装&#xff0c;mongoose会卡住)2. 调试下面讲讲如何调试服务器端的代码&#xff1a;我们最好借助一个叫node-insp…

Lua元表(Metatable)简易教程

文章目录0.友情链接1.引言2.创建一个元表2.1.__tostring方法2.2.__add和__mul方法2.3.__index方法2.4.__call方法3.完整代码0.友情链接 GitHUb上下载Lua编译器Lua菜鸟教程中的元表介绍&#xff08;较全&#xff0c;但功能性受限&#xff09;博客园内元表的介绍&#xff08;较详…

面试官:说一下 final 和 final 的 4 种用法?

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;重要说明&#xff1a;本篇为博主《面试题精选-基础篇》系列中的一篇&#xff0c;查看系列面试文章请关注我。Gitee 开源地址…

ruby 将字符串转为数组_Ruby程序将数组打印为字符串

ruby 将字符串转为数组将数组打印为字符串 (Printing an array as string) Given an array and we have to print it as a string in Ruby. 给定一个数组&#xff0c;我们必须在Ruby中将其打印为字符串。 Ruby provides you various alternatives for the single problem. The…