我陷入了这样的场景。
我正在用我的新MVC应用程序实现Identity 2.0。我想采用数据库优先方法,将用户Id设置为int。
为了实现这一点,我创建了
-
自定义用户存储-MyUserStore
public class MyUserStore : IUserLoginStore<AspNetUser>, IUserClaimStore<AspNetUser>, IUserRoleStore<AspNetUser>, IUserPasswordStore<AspNetUser>, IUserSecurityStampStore<AspNetUser>, IUserStore<AspNetUser>, IDisposable //where AspNetUser : AspNetUser { private readonly DemoPermissionDBContext _context; //private readonly Func<string, string> _partitionKeyFromId; public MyUserStore(DemoPermissionDBContext dbContext) { _context = dbContext; } public Task SetPasswordHashAsync(AspNetUser user, string passwordHash) { user.PasswordHash = passwordHash; return Task.FromResult(0); } //And other methods implementation }
这里AspNetUser是EF生成的用户类,我从Identity.IUser 继承了它
-
自定义用户管理器-AppUserManager
public class AppUserManager : Microsoft.AspNet.Identity.UserManager<AspNetUser> { MyUserStore _store = null; public AppUserManager(MyUserStore store) : base(store) { _store = store; } }
-
自定义密码散列-MyPasswordHasher
public class MyPasswordHasher : IPasswordHasher { public string HashPassword(string password) { return password; } public PasswordVerificationResult VerifyHashedPassword( string hashedPassword, string providedPassword) { if (hashedPassword == HashPassword(providedPassword)) return PasswordVerificationResult.Success; else return PasswordVerificationResult.Failed; } }
-
自定义索赔主体-AppClaimsPrincipal
public class AppClaimsPrincipal : ClaimsPrincipal { public AppClaimsPrincipal(ClaimsPrincipal principal):base(principal) { } public int UserId { get { return int.Parse(this.FindFirst(ClaimTypes.Sid).Value); } }
现在,当我注册用户时,在将用户实际保存到DB之前,UserManager.CreateAsync应该自动调用SetPasswordHashAsync同时,正在正确调用SetSecurityStampAsync。
我在我的AccountController中做的事情是这样的,
public AppUserManager UserManager { get; private set; }
public AccountController(AppUserManager userManager)
{
this.UserManager = userManager;
this.UserManager.PasswordHasher = new MyPasswordHasher();
}
这就是我如何为用户表和数据库实现身份到用户int主键的方法。
问题:
当我的用户被插入数据库时,它并没有包含密码散列。该记录的密码哈希为null。调试代码时,我发现不仅调用了SetPasswordHashAsync。它不执行薄荷糖。是什么导致了这个问题?我已经逐行检查了整个代码,但没有成功。为了使用自定义密码哈希器,我需要在web.config中添加什么吗?
我不确定我是否遗漏了什么。非常感谢您的帮助。
我看不到您在userManager中设置MyPasswordHasher
。添加
this.PasswordHasher = new MyPasswordHasher();
在CCD_ 2的构造函数中。
此外,您不需要覆盖ClaimsPrincipal
来获得UserId
。这可通过User.Identity.GetUserId()
获得,可在Microsoft.AspNet.Identity
命名空间中获得。
此外,我发现在IPrincipal
上使用扩展方法来获取声明的值更容易——这比使用自定义主体类型更容易。
Assteve16351提到的UserManager.CreateAsync(user, password)
应该被调用,而不是UserManager.CreateAsync(user)
。
我最近遇到了和你完全相同的问题,并用UserManager.CreateAsync(user, password)
解决了这个问题。