ASP.NET Core中的密码重置令牌提供程序 - 找不到IUserTokenProvider。

8

你好,

为了使密码重置工作正常,我需要将一个IUserTokenProvider实例注册到DI中。

如果没有它,我会在以下行遇到异常:

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

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

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

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

谢谢。

6个回答

26

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

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));

它接收了空字符串而不是令牌。 - EgoPingvina

12

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

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

你可以在这里找到更多说明。


9

我不确定这是一种解决方法还是正常的做法,但是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:开了一个问题以阐明


7
你需要深入研究.NET Core代码,查找AddIdentity内部的操作。
我发现以下方案适用于我们,因为我们无法使用.AddIdentity(),因为它会覆盖IdentityServer4中间件。
相反,我们为所有UserManager所需的接口添加了暂时服务,然后使用IdentityBuilder类来添加令牌提供程序。
注意:下面的User类继承自IdentityUser,因为我们需要自定义用户表。
// 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>>();

1
在startup类的ConfigureServices()方法中添加.AddDefaultTokenProviders();。
 `in public void ConfigureServices(IServiceCollection services)
    {
     services.AddIdentity<RegisterUser, IdentityRole>()
                    .AddEntityFrameworkStores<ContextClass>()
                    .AddDefaultTokenProviders();
    }
    `

0
        services.AddIdentityCore<User>()
        .AddEntityFrameworkStores<ContextClass>()
        .AddDefaultTokenProviders();

这是 AddIdentityCore 的版本,仅用于您添加用户,您可能需要它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接