ASP.NET 核心中的密码重置令牌提供程序 - 未找到 IUserTokenProvider

Password reset token provider in ASP.NET core - IUserTokenProvider not found

您好,

为了进行密码重置工作,我需要在 DI 中注册一个 IUserTokenProvider 实例。

没有它我会在以下行得到异常:

var result = await _userManager.ResetPasswordAsync(user, token, password);
"No IUserTokenProvider named 'PasswordResetTokenProvider' is registered."

这是有道理的,所以我尝试在 DI 中注册它:

services.AddSingleton<IUserTokenProvider<User>, DataProtectorTokenProvider<User>>();

但是接口IUserTokenProvider不存在。你知道怎么解决吗?

谢谢

我不确定这是解决方法还是正常方法,但 IUserTwoFactorTokenProvider 界面似乎是正确的方法。 IUserTokenProvider 似乎不再存在。

发现我必须在身份中手动注册提供商:

services.AddIdentity<User, Role>(options =>
            {
                ...
                options.Tokens.ProviderMap.Add("Default", new TokenProviderDescriptor(typeof(IUserTwoFactorTokenProvider<User>)));
            })

以及ConfigureServices中的可选配置:

services.Configure<DataProtectionTokenProviderOptions>(o =>
        {
            o.Name = "Default";
            o.TokenLifespan = TimeSpan.FromHours(1);
        });

密码重置/电子邮件验证令牌现在可以使用了。

PS: Opened an issue for clarification

您可以指定内置提供程序之一;

services.AddIdentity<User, Role>(options =>{
        options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
    })
    .AddDefaultTokenProviders();

或者创建您自己的 IUserTwoFactorTokenProvider 并像这样注册它;

services.AddIdentity<User, Role>(options => {
    options.Tokens.PasswordResetTokenProvider = nameof(MyTokenProvider);
})
.AddTokenProvider<MyTokenProvider>(nameof(MyTokenProvider));

您必须深入挖掘 .NET Core 代码并找到 AddIdentity 正在执行的内部操作。

我发现以下对我们有用,因为我们无法使用 .AddIdentity(),因为它覆盖了 IdentityServer4 中间件。

相反,我们为 UserManager 所需的所有接口添加了瞬变,然后使用 IdentityBuilder class 添加令牌提供程序。

注意 下面的用户 class 继承自 IdentityUser 因为我们需要自定义我们的用户 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>>();

在 startup.cs 中添加或更正以下行:

services.AddIdentity<User, UserRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

您可以找到更多描述here

在startupclass的ConfigureServices()方法中添加.AddDefaultTokenProviders();

 `in public void ConfigureServices(IServiceCollection services)
    {
     services.AddIdentity<RegisterUser, IdentityRole>()
                    .AddEntityFrameworkStores<ContextClass>()
                    .AddDefaultTokenProviders();
    }
    `
        services.AddIdentityCore<User>()
        .AddEntityFrameworkStores<ContextClass>()
        .AddDefaultTokenProviders();

AddIdentityCore版本只为你添加用户,你可能需要它。