Reputation: 5946
I'm starting my application, logging in and change my password (I'm using the default net .core identity):
IdentityResult identityResult =
await _userManager.ChangePasswordAsync(
applicationUser,
model.CurrentPassword,
model.NewPassword);
this works and in the database the new hashed password is stored.
Then, I'm logging out and try to login with the new password. But
if (await _userManager.CheckPasswordAsync(user, password))
return false
. (Logging in with the old password still works, and I'm not caching anything)
When I'm restarting my application and trying to login with the new password, it works. I guess it's somewhere a problem with that PasswordStore (is there a caching?)? Any other suggestions what I may have forgotten or why this doesn't work?
edit:
the complete change password method:
[HttpPut]
[Route("api/user/changepassword/{ident}")]
public async Task<bool> ChangePassword(int ident, [FromBody]ChangePasswordModel model)
{
if (!ModelState.IsValid)
return false;
ApplicationUser applicationUser;
if ((applicationUser = await _userManager.FindByIdAsync(ident.ToString())) == null)
return false;
IdentityResult identityResult = await _userManager.ChangePasswordAsync(applicationUser, model.CurrentPassword, model.NewPassword);
return identityResult.Succeeded;
}
part from my startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Upvotes: 2
Views: 1987
Reputation: 5946
So I guess, the AspNetCores UserManager<TUser>
caches data (and I guess it's cached by the PasswordStore? Please correct me, if wrong.)
I could fix it by getting a new UserManager<TUser>
-object when validating the password in the tokenprovider-middleware.
private async Task _generateToken(HttpContext context)
{
StringValues username = context.Request.Form["username"];
StringValues password = context.Request.Form["password"];
var usermanager = context.RequestServices.GetRequiredService<UserManager<ApplicationUser>>();
ApplicationUser user = await usermanager.FindByNameAsync(username);
if (user == null)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("Invalid username or password.");
return;
}
ClaimsIdentity identity = await _getIdentity(user, password);
if (identity == null)
{
await usermanager.AccessFailedAsync(user);
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("Invalid username or password.");
return;
}
I can create a new UserManager<TUser>
with the following extension-method:
var usermanager = context.RequestServices.GetRequiredService<UserManager<TUser>>();
when validating the password we now validate the new data and the new password is correct (and the previous password is incorrect).
Upvotes: 1