I'm a little flummoxed by trying to implement the IPasswordStore in the new asp.net mvc 5. I want to use my own ORM.
Take this familiar code snippet from the scaffolded 'AccountController' that runs when the 'register' screen is used in the example project.
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.UserName };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
the
var result = await UserManager.CreateAysnc(user, model.Password)
line first calls the IPasswordStore function
public Task SetPasswordHashAsync(TUser user, string passwordHash)
without having first called from IUserStore
public Task CreateAsync(TUser user)
How do I set the password hash if the user isn't created in the db yet? Furthermore, we actually don't even know if we can create the proposed 'user' because we haven't checked to see if the username is taken yet using
public Task<TUser> FindByNameAsync(string userNameIn)
which is called right afterwards.
Any ideas?
You are right in noticing that you probably should not persist the password hash for the user before the user is created.
You could save the password hash to a location that will be reverted if the user is not actually created anyway. The password should not be stored untill the user is created and stored, i.e. in CreateAsync(TUser user)
.
The IdentityUser in the EntityFramework implementation would be such a location, and it would enable you to store both user and password information in the CreateAsync method. I am not saying you should reference the Identity.EntityFramework assembly, just saying that a User object that has both User and PasswordHash info similar to the IdentityUser is one possible solution.
Always set the password hash property of your user object in the IUserPasswordStore.SetPasswordHashAsync
method body as the IUser
interface doesn't define the property so UserManager
can't set it. If you do this and then only update the user database record if the user exists you can add the password hash when you finally create your user in the IUserStore.CreateAsync
method.
This principal also works for the IUserSecurityStampStore.SetSecurityStampAsync
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With