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 自定义使用现有的表—登录实现相关推荐

  1. ASP.NET Core Identity自定义数据库结构和完全使用Dapper而非EntityFramework Core

    前言 原本本节内容是不存在的,出于有几个人问到了我:我想使用ASP.NET Core Identity,但是我又不想使用默认生成的数据库表,想自定义一套,我想要使用ASP.NE Core Identi ...

  2. 剖析 Microsoft.AspNetCore.Identity 的精髓 ——菜鸟入门

    学习目录 前言 初级 菜鸟入门 配置详解 简单二次开发 进阶 UserManager 解析 RoleManager 解析 Validator 解析 SignInManager 解析 关于如何使用 博客 ...

  3. 【FBA】SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用...

    //http://www.cnblogs.com/OceanEyes/p/custom-provider-in-sharepoint-2013-fba-authentication.html 由于项目 ...

  4. AspNet Identity 和 Owin 谁是谁

    英文原文:http://tech.trailmax.info/2014/08/aspnet-identity-and-owin-who-is-who/ 最近我发现Stackoverflow上有一个非常 ...

  5. Gin 框架学习笔记(01)— 自定义结构体绑定表单、绑定URI、自定义log、自定义中间件、路由组、解析查询字符串、上传文件、使用HTTP方法

    要实现一个 API 服务器,首先要考虑两个方面:API 风格和媒体类型.Go 语言中常用的 API 风格是 RPC 和 REST,常用的媒体类型是 JSON.XML 和 Protobuf.在 Go A ...

  6. R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format)、指定行标识符变量、并自定义生成的长表的标识符列的名称

    R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format).指定行标识符变量.并自定义生成的长表的标识符列的名称 目录

  7. 转:iFire:玩聚 SRBacks 自定义脚本及样式表

    感谢iFire的第一时间修改并试用,而且调试出如此清新的样式. 下面转贴一下他的自定义脚本和样式表: 玩聚 SRBacks 自定义脚本及样式表 admin @ 2009-01-11 02:34 59 ...

  8. dotnet安装包时找不到依赖关系_无法加载文件或程序集'Microsoft.AspNet.TelemetryCorrelation'或其依赖项之一 . 该系统找不到指定的文件...

    我在IIS 7(本地Windows 10 Pro)下有两个Web应用程序 . 根目录是MVC .Net Version 4.7.1 . 到目前为止,一切似乎都很好 . 但是,在默认站点根目录下设置为单 ...

  9. 命名空间“Microsoft.AspNet”中不存在类型或命名空间名“Mvc”

    问题: 错误 CS0234 命名空间"Microsoft.AspNet"中不存在类型或命名空间名"Mvc"(是否缺少程序集引用?) 解决方案: 打开文件夹 Us ...

最新文章

  1. php gif裁剪,PHP实现图片裁剪与缩放的几种方法
  2. 一个支持Abort的BackgroundWorker
  3. 让DNN为您的手机提供内容
  4. 设计模式(一)Chain Of Responsibility责任链模式
  5. 文档词频矩阵_论文理解:从词嵌入到文档距离
  6. JSON Assertion(JSON断言)
  7. 如何为 Mac 添加新语言?
  8. android 地理位置改变,Android中修改地理位置信息
  9. 服务器视频文件外链,视频图床 视频外链网站 视频上传外链分享
  10. Excel中的Vlookup函数操作实例
  11. Android两种方式实现横向滚动图标+指示器
  12. 国内支持Amazon Alexa的智能家居
  13. 打单词游戏 html5,html打字游戏
  14. react-router如何配置可选参数
  15. 计算机平面设计福建专科学校,2016年福建单招视觉传达设计专业的学校有哪些?...
  16. 第8章 IP代理使用技巧与实战(8.1 结合Requests库使用IP代理)
  17. AR+LBS线下社交游戏尝试
  18. vue+h5仿微信网页版聊天室vueWebChat项目
  19. MySql基础篇——变量、流程控制与游标
  20. PPT之幻灯片中的大纲选项卡

热门文章

  1. bootstrap 滚动 进度条_bootstrap实现动态进度条效果
  2. python pandas合并多个excel_python pandas合并多个excel(xls和xlsx)文件(弹窗选择文件夹和保存文件)...
  3. 基本的排序算法php,php四种基础排序算法
  4. ext get id js_Ext.getCmp(“id”) 简单应用 | 学步园
  5. 计算机一级电子表格插入表格,计算机一级电子表格
  6. 畅想未来计算机的绘画作品小学生,畅想未来儿童画绘画作品大全
  7. 聚宽macd底背离_许多散户不知道:MACD月线金叉,MACD月金叉都会带来一波牛市!...
  8. TortoiseGit与github实现项目的上传
  9. linux查看内存_嵌入式操作系统的内存,你了解多少?
  10. stn算子_深度学习常用算子(二)