问题
Hello,
I googled thoroughly but there is hundred examples from ASP.NET but nothing about ASP.NET Core.
In order to getting password reset work I need to register an IUserTokenProvider instance into DI.
Without it I get exception at following line:
var result = await _userManager.ResetPasswordAsync(user, token, password);
Exception
"No IUserTokenProvider named 'PasswordResetTokenProvider' is registered."
That makes sense so I tried to register it in the DI:
services.AddSingleton<IUserTokenProvider<User>, DataProtectorTokenProvider<User>>();
But the interface IUserTokenProvider
does not exists. I'm using Microsoft.AspNetCore.Identity
in the file. It even does not exists in project gitlab.
Well, after digging in identity source code I find a similar interface IUserTwoFactorTokenProvider<T>
. Let's use this instead:
services.AddSingleton<IUserTwoFactorTokenProvider<User>, DataProtectorTokenProvider<User>>();
... and no luck.
TL;DR:
Please - how to get the password reset in ASP.NET Core work? At best with some example.
Thank you in advance.
回答1:
You can specify one of the built in providers;
services.AddIdentity<User, Role>(options =>{
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
})
.AddDefaultTokenProviders();
Or create your own IUserTwoFactorTokenProvider and register it like so;
services.AddIdentity<User, Role>(options => {
options.Tokens.PasswordResetTokenProvider = nameof(MyTokenProvider);
})
.AddTokenProvider<MyTokenProvider>(nameof(MyTokenProvider));
回答2:
add or correct following lines in startup.cs:
services.AddIdentity<User, UserRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
you can found more description here
回答3:
I'm not sure if it's workaround or normal approach, but the IUserTwoFactorTokenProvider
interface seems to be a right way. IUserTokenProvider appears to no longer exists.
Figured out that I have to register the provider manually in the identity:
services.AddIdentity<User, Role>(options =>
{
...
options.Tokens.ProviderMap.Add("Default", new TokenProviderDescriptor(typeof(IUserTwoFactorTokenProvider<User>)));
})
And the optional configuration in ConfigureServices
:
services.Configure<DataProtectionTokenProviderOptions>(o =>
{
o.Name = "Default";
o.TokenLifespan = TimeSpan.FromHours(1);
});
And the password reset / email validation tokens are working now.
PS: Opened an issue for clarification
回答4:
You have to dig deep into the .NET Core code and find what internals the AddIdentity
is doing.
What I found was the following that worked for us as we could not use .AddIdentity()
as it overrode the IdentityServer4 middleware.
Instead, we added transients for the all the interfaces needed for UserManager and then used IdentityBuilder class to add the token provider.
NOTE The User class below inherits from IdentityUser
as we needed to customize our user table.
// add User Manager related objects into DI configuration
services.AddTransient<IUserStore<User>, UserStore<User, IdentityRole<string>, ApplicationDbContext>>();
services.AddTransient<IRoleStore<IdentityRole<string>>, RoleStore<IdentityRole<string>, ApplicationDbContext>>();
services.AddTransient<IPasswordHasher<User>, PasswordHasher<User>>();
services.AddTransient<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services.AddTransient<IdentityErrorDescriber>();
var identityBuilder = new IdentityBuilder(typeof(User), typeof(IdentityRole<string>), services);
identityBuilder.AddTokenProvider("Default", typeof(DataProtectorTokenProvider<User>));
services.AddTransient<UserManager<User>>();
来源:https://stackoverflow.com/questions/40445980/password-reset-token-provider-in-asp-net-core-iusertokenprovider-not-found