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
Microsoft.AspNet.Identity 自定义使用现有的表—登录实现相关推荐
- ASP.NET Core Identity自定义数据库结构和完全使用Dapper而非EntityFramework Core
前言 原本本节内容是不存在的,出于有几个人问到了我:我想使用ASP.NET Core Identity,但是我又不想使用默认生成的数据库表,想自定义一套,我想要使用ASP.NE Core Identi ...
- 剖析 Microsoft.AspNetCore.Identity 的精髓 ——菜鸟入门
学习目录 前言 初级 菜鸟入门 配置详解 简单二次开发 进阶 UserManager 解析 RoleManager 解析 Validator 解析 SignInManager 解析 关于如何使用 博客 ...
- 【FBA】SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用...
//http://www.cnblogs.com/OceanEyes/p/custom-provider-in-sharepoint-2013-fba-authentication.html 由于项目 ...
- AspNet Identity 和 Owin 谁是谁
英文原文:http://tech.trailmax.info/2014/08/aspnet-identity-and-owin-who-is-who/ 最近我发现Stackoverflow上有一个非常 ...
- Gin 框架学习笔记(01)— 自定义结构体绑定表单、绑定URI、自定义log、自定义中间件、路由组、解析查询字符串、上传文件、使用HTTP方法
要实现一个 API 服务器,首先要考虑两个方面:API 风格和媒体类型.Go 语言中常用的 API 风格是 RPC 和 REST,常用的媒体类型是 JSON.XML 和 Protobuf.在 Go A ...
- R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format)、指定行标识符变量、并自定义生成的长表的标识符列的名称
R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format).指定行标识符变量.并自定义生成的长表的标识符列的名称 目录
- 转:iFire:玩聚 SRBacks 自定义脚本及样式表
感谢iFire的第一时间修改并试用,而且调试出如此清新的样式. 下面转贴一下他的自定义脚本和样式表: 玩聚 SRBacks 自定义脚本及样式表 admin @ 2009-01-11 02:34 59 ...
- dotnet安装包时找不到依赖关系_无法加载文件或程序集'Microsoft.AspNet.TelemetryCorrelation'或其依赖项之一 . 该系统找不到指定的文件...
我在IIS 7(本地Windows 10 Pro)下有两个Web应用程序 . 根目录是MVC .Net Version 4.7.1 . 到目前为止,一切似乎都很好 . 但是,在默认站点根目录下设置为单 ...
- 命名空间“Microsoft.AspNet”中不存在类型或命名空间名“Mvc”
问题: 错误 CS0234 命名空间"Microsoft.AspNet"中不存在类型或命名空间名"Mvc"(是否缺少程序集引用?) 解决方案: 打开文件夹 Us ...
最新文章
- php gif裁剪,PHP实现图片裁剪与缩放的几种方法
- 一个支持Abort的BackgroundWorker
- 让DNN为您的手机提供内容
- 设计模式(一)Chain Of Responsibility责任链模式
- 文档词频矩阵_论文理解:从词嵌入到文档距离
- JSON Assertion(JSON断言)
- 如何为 Mac 添加新语言?
- android 地理位置改变,Android中修改地理位置信息
- 服务器视频文件外链,视频图床 视频外链网站 视频上传外链分享
- Excel中的Vlookup函数操作实例
- Android两种方式实现横向滚动图标+指示器
- 国内支持Amazon Alexa的智能家居
- 打单词游戏 html5,html打字游戏
- react-router如何配置可选参数
- 计算机平面设计福建专科学校,2016年福建单招视觉传达设计专业的学校有哪些?...
- 第8章 IP代理使用技巧与实战(8.1 结合Requests库使用IP代理)
- AR+LBS线下社交游戏尝试
- vue+h5仿微信网页版聊天室vueWebChat项目
- MySql基础篇——变量、流程控制与游标
- PPT之幻灯片中的大纲选项卡
热门文章
- bootstrap 滚动 进度条_bootstrap实现动态进度条效果
- python pandas合并多个excel_python pandas合并多个excel(xls和xlsx)文件(弹窗选择文件夹和保存文件)...
- 基本的排序算法php,php四种基础排序算法
- ext get id js_Ext.getCmp(“id”) 简单应用 | 学步园
- 计算机一级电子表格插入表格,计算机一级电子表格
- 畅想未来计算机的绘画作品小学生,畅想未来儿童画绘画作品大全
- 聚宽macd底背离_许多散户不知道:MACD月线金叉,MACD月金叉都会带来一波牛市!...
- TortoiseGit与github实现项目的上传
- linux查看内存_嵌入式操作系统的内存,你了解多少?
- stn算子_深度学习常用算子(二)