Reputation: 21
I am building a .net core 2 Identity application. It uses JWT token for a Vuejs front end.
I am writing the update password controller that checks the token first then changes the password using ChangePasswordAsync
but I keep getting the response:
{Failed : PasswordMismatch}.
My controller code is below. I have successfully written the login and register controllers but having no luck with this. The logged in user, ctrustUser
is successfully returned, so then I am using that data to pass into ChangePasswordAsync
the logged in user data.
Please can you help me.
[Authorize(Policy = "ApiUser")]
[Route("api/[controller]/[action]")]
public class AccountsEditController : Controller
{
private readonly ClaimsPrincipal _caller;
private readonly ApplicationCtrustUsersDbContext _appDbContext;
private readonly UserManager<AppAdminUser> _userManager;
private readonly IMapper _mapper;
public AccountsEditController(UserManager<AppAdminUser> userManager, ApplicationCtrustUsersDbContext appDbContext, IHttpContextAccessor httpContextAccessor, IMapper mapper)
{
_userManager = userManager;
_caller = httpContextAccessor.HttpContext.User;
_appDbContext = appDbContext;
_mapper = mapper;
}
// POST api/accountsedit/updatepassword
[HttpPost]
public async Task<IActionResult>UpdatePassword([FromBody]UpdatePasswordViewModel model)
{
// simulate slightly longer running operation to show UI state change
await Task.Delay(250);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// retrieve the user info
var userId = _caller.Claims.Single(c => c.Type == "id");
var ctrustUser = await _appDbContext.CtrustUser.Include(c => c.Identity).SingleAsync(c => c.Identity.Id == userId.Value);
AppAdminUser userIdentity = new AppAdminUser();
userIdentity.Id = ctrustUser.IdentityId;
userIdentity.UserName = ctrustUser.Identity.UserName;
userIdentity.Email = ctrustUser.Identity.Email;
//AppAdminUser user = _mapper.Map<AppAdminUser>(model);
var result = await _userManager.ChangePasswordAsync(userIdentity, model.Password, model.NewPassword);
if (!result.Succeeded) return new BadRequestObjectResult(Errors.AddErrorsToModelState(result, ModelState));
return new OkObjectResult("Password updated");
}
}
Upvotes: 0
Views: 1557
Reputation: 21
Solved it, by using:
var user = await _userManager.FindByNameAsync(...);
then passing that into ChangePasswordAsync
var result = await _userManager.ChangePasswordAsync(user, model.Password, model.NewPassword);
Upvotes: 1
Reputation: 26
The error {Failed : PasswordMismatch} is due to the "currentPassword" parameter your passing in not matching the existing password against that user (the second parameter in the method) which you're sending in as "model.Password". The method validates this value to ensure the user is who they say they are.
public virtual Task<IdentityResult> ChangePasswordAsync(TUser user, string
currentPassword, string newPassword);
I'd suggest debugging that to ensure that you're passing in the users current password, not their new password, and ensure you're retrieving the correct user.
Upvotes: 1