GeneratePasswordResetTokenAsync and Data Protection Operation errors
January 8, 2016 17 Comments
I recently ran into a problem with the GeneratePasswordResetTokenAsync() method that is part of ASP.NET Identity, and it took me a while to find what turned out to be a simple solution.
The problem was occurring in some fairly standard "Forgot Password" code. The code generated a reset password token, embedded the token in an email message, and sent the message to a user. The relevant part of the code looked something like this:
// Generate a password reset token
string t = await UserManager.GeneratePasswordResetTokenAsync(user.Id);var callbackUrl = Url.Action( "ResetPassword" , "Account" , new { id = user.Id, token = t}, protocol: Request.Url.Scheme);
string email = "Reset your password by navigating to " + callbackUrl + ".";// Send the email
await UserManager.SendEmailAsync(userId, null, null, "Reset your password", email);
The first line of the code…
string t = await UserManager.GeneratePasswordResetTokenAsync(userId);
… specifically the GeneratePasswordResetTokenAsync method, was supposed to generate the token. Instead, it produced the following error:
The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread’s user context, which may be the case when the thread is impersonating.
This was occurring on a standard single-server IIS installation… no Azure or Amazon EC2 or web farm was involved. (OK, technically it WAS part of a load balanced pair of servers, but my tests were isolated to a single machine). In addition, the same web site was running successfully at another location, on another single server IIS installation.
All of my initial research into the problem resulted in articles, blog posts, and StackExchange threads about this error occurring when running on Azure. I could find nothing at all about running on a single in-house server. And, everything found suggested various code changes, most of them centered around the same theme… overriding the default UserTokenProvider.
Examples of the type of information that I was finding can be found here and here.
Much of that information seeded to have merit, but the Azure trigger for the issue did not accurately describe my scenario, and I did not want to start modifying code when I wasn’t 100% sure it was the solution I needed.
And then buried in a StackExchange thread with a bunch of suggestions for code updates, I found this comment. Reproduced here, the comment was:
i had the same issues except i was hosting on amazon ec2. i was able to resolve it by going to the application pool in iis and (under advanced settings after a right click) setting process model – load user profile = true.
That was the solution! The Load User Profile setting for the App Pool was in fact set to False. Setting the value to True solved the problem.
In conclusion, if you run into the "data protection operation was unsuccessful" error when calling GeneratePasswordResetTokenAsync(), and you are not running on Azure or EC2 or a similarly hosted configuration, make sure that the Load User Profile setting for the site’s App Pool is True.