我正在使用ASP。. NET Identity 2和Entity Framework 5(因为我们的Oracle数据提供程序不支持EF6)。由于某些原因,UserManager.PasswordHasher.VerifyHashedPassword
的密码验证总是失败。
我的UserStore
类包含:
public Task SetPasswordHashAsync(IccmUser user, string passwordHash)
{
IPasswordHasher hasher = new PasswordHasher();
var t = Task.Run(() => {
user.PasswordHash = hasher.HashPassword(passwordHash);
});
return t;
}
密码(显然是散列的)存储在数据库中。因此,这段代码似乎工作得很好。
我的AccountController
做这样的密码验证:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(SignInModel model, string returnUrl)
{
if (ModelState.IsValid) {
// This fails:
//var user = await UserManager.FindAsync(model.UserName, model.Password);
// Thus: do it step by step.
PasswordVerificationResult result = PasswordVerificationResult.Failed;
// Step 1: find user.
IccmUser user = await UserManager.FindByNameAsync(model.UserName);
if (user == null) {
ModelState.AddModelError("", "Couldn't find the user.");
} else {
// Step 2: validate password
result = UserManager.PasswordHasher.VerifyHashedPassword(user.PasswordHash, model.Password);
if (result != PasswordVerificationResult.Success) {
ModelState.AddModelError("", "The password is not valid.");
} else {
// Step 3: sign-in user.
await SignInAsync(user, model.RememberMe);
return Redirect(returnUrl);
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
步骤2中的VerifyHashedPassword()
总是返回Failed
。两个参数(PasswordHash
和Password
)都被正确传入。
错误在UserStore实现中。SetPasswordHashAsync()
不应该对密码进行散列。相反,它从UserManager.CreateAsync()
接收散列密码。因此,UserStore
中的以下更改达到了目的:
public Task SetPasswordHashAsync(IccmUser user, string passwordHash)
{
return Task.FromResult(user.PasswordHash = passwordHash);
}
不好意思。