ASP.NET Core 2.2 Identity - UserManager.ResetPasswordAsync always Fails with Invalid Token

可紊 提交于 2019-12-24 15:07:05

问题


As per the title I have attempted to setup a simple ASP.NET Core 2.2 Web API project (so nothing to do with MVC Razor Pages or an UI).

I have been following this Microsoft guide Account confirmation and password recovery in ASP.NET Core but obviously adapted it for my Web API project which consists of the following four endpoints:

  • CreateUserAsync
  • ConfirmEmailAsync
  • PasswordResetEmailAsync
  • ResetPasswordAsync

Names are pretty self-explanatory the first two endpoints deal with creating a user, sending out an email using SendGrid and then the second endpoint deals with validating the confirmation token and confirming the user account.

So far so good all works as intended the token is correctly validated and the AspNetUser table row field EmailConfirmed is set to true (1). Apologies for got to mention at this point I had already scaffolded up the AspNetUser related tables using Entity Framework Migrations (Add-Migration command).

Now the third and fourth endpoints deal with the scenario of a user requesting a password reset token to then use to reset their password so endpoint number 3 PasswordResetEmailAsync reuses the same code as ConfirmEmailAsync endpoint first validating the user exists with UserManager.FindByNameAsync method and then passes this type ApplicationUser object (derived from IdentityUser) into the FindByNameAsync method which then hits the backing store and pulls out the user we created earlier (this works as intended):

var result = await _userManager
                .ResetPasswordAsync(user, token, theNewPassword)
                .ConfigureAwait(false);

This always returns the following (used Object Exporter add-in for this):

{
    "Errors": 
    [
        {
            "Code": "InvalidToken",
            "Description": "Invalid token."
        } 
    ], 
    "Succeeded": false,
    "_errors": 
}

As you can see from the JSON snippet above the token is deemed invalid however when I compared the generated token to the one being passed into the ResetPasswordAsync endpoint its the same:

CfDJ8NKO7RlW/idPs+/v0VVN8vv99DYu3b4zYHddSIlvUBHjcThOMG85zegMIJ6AUpQJXpC0Ouk0QW8hVVDIRUgT7u0TnUU+kJePskU2UMRaul0NtddoeJ30LsOe62K8lMqm9OyC8+CsU9nZZFKIWRDoJxnGCAJiznVukulFX9BxAhnFN+ocOHZBEwIVw9w/86wJRI1WKegiemcgWmepEZalBzU8bWHQHzKbHd4aIfahfK4OVcYNwPo0K1+5ypE4Jx1Mpg==

The above password is sanitised when generating the reset token email using WebUtility.UrlEncode method and decoded back in the ResetPasswordAsync endpoint using WebUtility.UrlDecode.

I used KDiff3 to confirm both token strings are identical and there is only one user in the AspNetUser table yet the token is always invalid and the reset password process fails.

The StartUp.cs class is nothing special looks like the example provided in the above tutorial I mentioned, key point being that I am adding an Identity provider on startup:

services.AddDefaultIdentity<ApplicationUser>(config =>
{
    config.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<AuthContext>();

This is driving me crazy and I have lost confidence in ASP.NET Core 2.2 Identity with regards to working with a Web API project. Why am I doing it this way? The rest of the world doesn't use MVC or Razor Pages, in this day and age everything is headless and the front end (whatever it may be React, Angular etc) consumes endpoints and the other reason is that I am build a bunch of Microservices sitting behind an Azure Application Gateway.

Thanks in advance.

来源:https://stackoverflow.com/questions/56013673/asp-net-core-2-2-identity-usermanager-resetpasswordasync-always-fails-with-inv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!