2

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();
10
  • Does that user variable have the updated (new hash in the database) password? Commented Apr 26, 2018 at 19:00
  • @CamiloTerevinto the database has the new hashed password stored. Poorly I can't debug CheckPasswordAsync it's part of the .net core identity. Commented Apr 26, 2018 at 19:02
  • 1
    I asked for the user variable, when you use _userManager.CheckPasswordAsync(user, from where does that user come from? Commented Apr 26, 2018 at 19:03
  • ahh sorry @CamiloTerevinto misunderstood you. a few lines before I search him with ApplicationUser user = await _userManager.FindByNameAsync(username); - so in the same context I get him new. But the user contains the old password hash. I saw, here is a user-store too in the usermanager Commented Apr 26, 2018 at 19:10
  • So, the problem is that you are retrieving an old user, not that the password verification is incorrect. Can you add the entire method for the password change? Commented Apr 26, 2018 at 19:15

1 Answer 1

1

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).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.