I'm trying to implement password reset functionality with nightly build of ASP.NET Identity 1.1. There is a UserManager.GetPasswordResetToken method, but it throws an exception "No ITokenProvider is registered". Is there an built in token provider in ASP.NET Identity? If yes, how I can register it? If no, how I can implement one? Will be default Token Provider in the 1.1. release? And final question, is there an estimated 1.1 release date?
问题:
回答1:
The default token provider implementation is found in the Microsoft.Identity.Owin
package:
/// <summary>
/// Token provider that uses a DataProtector to generate encrypted tokens
/// </summary>
public class DataProtectorTokenProvider : ITokenProvider {
public DataProtectorTokenProvider(IDataProtector protector)
And you do something like this to wire one up using the default data protection provider from your OWIN IAppBuilder
IDataProtectionProvider provider = app.GetDataProtectionProvider();
if (provider != null)
{
manager.PasswordResetTokens = new DataProtectorTokenProvider(provider.Create("PasswordReset"));
manager.UserConfirmationTokens = new DataProtectorTokenProvider(provider.Create("ConfirmUser"));
}
回答2:
If someone looking for solution under AspNet.Identity 2.0 beta1 version.
Only this need to be modified.
UserManager.UserTokenProvider = new DataProtectorTokenProvider
<SecurityUser, string>(provider.Create("UserToken"))
as IUserTokenProvider<SecurityUser, string>;
PasswordResetTokens
and UserConfirmationTokens
is merged into UserTokenProvider
property and token provider class is also modified.
回答3:
Another way to do this (building on the other answers but simplifying it some) is to change Startup.Auth.cs
so it looks similar to this:
public partial class Startup
{
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public void ConfigureAuth(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
}
}
Then, modify the default constructor in AccountController.cs
so that it looks similar to this:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
if (Startup.DataProtectionProvider != null)
{
this.UserManager.PasswordResetTokens = new DataProtectorTokenProvider(Startup.DataProtectionProvider.Create("PasswordReset"));
this.UserManager.UserConfirmationTokens = new DataProtectorTokenProvider(Startup.DataProtectionProvider.Create("ConfirmUser"));
}
}
回答4:
Ok, answering my own question based on @hao-kung reply. First add static constructor and UserManagerFactory to Statrup class (startup.auth.cs)
public partial class Startup
{
static Startup()
{
UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
}
public static Func<UserManager<IdentityUser>> UserManagerFactory { get; set; }
public void ConfigureAuth(IAppBuilder app)
{
var manager = UserManagerFactory();
IDataProtectionProvider provider = app.GetDataProtectionProvider();
if (provider != null)
{
manager.PasswordResetTokens = new DataProtectorTokenProvider(provider.Create("PasswordReset"));
manager.UserConfirmationTokens = new DataProtectorTokenProvider(provider.Create("ConfirmUser"));
}
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
}
Then init UserManager in the AccountController using that UserManagerFactory
public AccountController() : this(Startup.UserManagerFactory())
{
}
public AccountController(UserManager<IdentityUser> userManager)
{
UserManager = userManager;
}
public UserManager<IdentityUser> UserManager { get; private set; }