UserManager VerifyUserTokenAsync Always False
Asked Answered
H

6

19

I'm generating a usertoken like so

public async Task GenerateCode()
{

    var code = await UserManager.GenerateUserTokenAsync("heymega", new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"));


}

I then pass the same token into another action via a separate request

public async Task ValidateCode(string code)
{

    var valid = await UserManager.VerifyUserTokenAsync(new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"), "heymega", code); //Returns False

}

However, the response from the VerifyUserTokenAsync method is always false.

If I were to generate the code and verify within the same action

public async Task GenerateCode()
{

    var code = await UserManager.GenerateUserTokenAsync("heymega", new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"));

    var valid = await UserManager.VerifyUserTokenAsync(new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"), "heymega", code); //Returns True

}

It returns true.

Why can't the Verify method verify the code in a separate request? Am I missing something obvious?

Houselights answered 29/4, 2015 at 11:18 Comment(0)
H
25

I finally figured this after pulling my hair out for hours. You need to URL encode the code and I decided to use the HttpUtility class for this.

HttpUtility.UrlEncode(code);

When it comes to verifying the code, you do not need to URL decode the code.

Houselights answered 29/4, 2015 at 12:16 Comment(6)
It took me too long to find this answer...but when I did it solved my issue! Thanks.Marble
I'm not sure what version of ASP.NET Identity you have installed. But I am using version 2.2.1 and I absolutely have to use HttpUtility.UrlDecode(code) when I verify the code. Otherwise, it ALWAYS returns false.Billy
If you have to use UrlDecode explicitly to verify the code then you probably double-encoded it when you created your URL. It shouldn't be necessary.Boycott
Using UrlDecode on the token did not work for me. I have not to decode the tokenGymno
I'd like to add that VerifyUserToken can certainly handle URL decoded tokens, so if you are seeing it return false I don't see how this could be the answer.Ung
+1 to most likely needing to use HttpUtility.UrlDecode before passing the token to VerifyUserTokenAsync. At least I seem to need it.Chlamys
R
3

Having just burned 2 days on this issue, here is another reason this might be happening to you.

In your Startup.cs - ConfigureServices(IServiceCollection services) method, ensure that:

services.AddAuthentication

Appears BEFORE

services.AddIdentity

Otherwise calls to VerifyUserTokenAsync will always return false

Radford answered 9/10, 2017 at 11:1 Comment(0)
M
0

Cannot solve this problem until haven't used this:

 UserManager.VerifyUserTokenAsync(userId, AccountLockedOutPurpose, code).WithCurrentCulture<bool>();

.WithCurrentCulture() - used in all methods such as ResetPasswordAsync etc.)

Michealmicheil answered 26/5, 2016 at 11:50 Comment(0)
U
0

In my situation I was instantiating a UserManager on demand when one was needed, as opposed to generating one per Owin context in my startup pipeline. Behavior wise, if I validated the token with the same instance of UserManager that created it, it would return true. But if I did an actual forgot password flow where the validation is in a separate request, it was always false.

Switching my setup so that a UserManager was created per owin context resolved the issue for me. Apparently there is some dependency on Owin when it comes to validating tokens.

            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
Ung answered 5/12, 2019 at 20:27 Comment(0)
B
0

Not sure if OP is using .Net Core or not, but if someone comes across this and you're using dependency injection, the solution for me was to scope the UserManager as a singleton.

services.AddSingleton<UserManager<YourUserAccountModel>>();

I believe this is because when the user clicks the confirm email link in their inbox, a new UserManager instance is injected to the controller and does not have the same key that was used to generate the token to begin with. Therefore it cannot verify the token.

Bisectrix answered 19/5, 2021 at 15:16 Comment(0)
O
0

For me, I got the same issue. and the solution was very simple.

In my case, I add the purpose with white space like this "Email Confirmation". the problem was solved when I removed any white space "EmailConfirmation".

bool IsTokenValed = await userManager.VerifyUserTokenAsync(user, userManager.Options.Tokens.EmailConfirmationTokenProvider, "EmailConfirmation", token);
Orose answered 11/1, 2022 at 4:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.