C# ASP.NET核心无效密码重置令牌
我有两台服务器使用相同的ASP.NET核心标识后端。我使用以下命令生成密码重置令牌:C# ASP.NET核心无效密码重置令牌,c#,asp.net-core,asp.net-core-identity,C#,Asp.net Core,Asp.net Core Identity,我有两台服务器使用相同的ASP.NET核心标识后端。我使用以下命令生成密码重置令牌: var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser); 我通过电子邮件链接发送此令牌。当用户单击链接时,他们会被带到一个单独的站点,该站点应提供一个用户界面来更改密码。以下代码处理用户提交令牌及其新密码的密码: var identityResult = await _userManager.ResetPa
var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);
我通过电子邮件链接发送此令牌。当用户单击链接时,他们会被带到一个单独的站点,该站点应提供一个用户界面来更改密码。以下代码处理用户提交令牌及其新密码的密码:
var identityResult = await _userManager.ResetPasswordAsync(applicationUser, code, password);
在第二台服务器上,标识结果总是返回false,因为令牌无效
通过查看源代码,我看到令牌是使用IP地址生成的,因此我理解令牌验证失败的原因
我的问题是如何在不同的机器上成功创建/验证令牌?在以前的ASP.NET形式中,我可能会使用共享机器密钥来防止出现这些情况。ASP.NET核心似乎没有类似的概念。据我所知,这似乎是一个使用DataProtection API的场景。不幸的是,我还没有看到如何将其应用于生成重置令牌的任何示例。我遇到了类似的问题。实际上,它不是关于2台服务器的。它是关于身份框架的。您可以从usermanager派生,也可以使用中心提供程序覆盖提供程序。但我尝试了一些不同的方法,效果很好。 首先,ConfirmEmail方法会查看数据库,如果您有一个数据库,则令牌和多个服务器之间不应该存在问题 在usermanager中,您应该像这样在构造函数中创建dataprovider
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
var dataProtectorProvider = Startup.DataProtectionProvider;
var dataProtector = dataProtectorProvider.Create("My Identity");
this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, string>(dataProtector);
//this.UserTokenProvider.TokenLifespan = TimeSpan.FromHours(24);
}
您应该在发送令牌之前对其进行编码。你应该这样做:
var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);
var encodedCode = HttpUtility.UrlEncode(token);
编码后,必须传递已编码的令牌,而不是生成的令牌。是否尝试在两个应用程序中将应用程序名称设置为相同的值
services.AddDataProtection().SetApplicationName("same for both apps");
p.S-我也遇到了同样的问题。不确定这是否是旧版本的遗留问题,但您需要设置机器密钥,以便它们以相同的方式对令牌进行加密。Core似乎没有机器密钥的概念,至少在web.config中没有。@Eric您知道这一点吗?我遇到了确切的问题您在哪里定义了Startup.DataProtectionProvider?默认情况下它不在那里?您的启动类是从某个基类继承的,还是您自己定义了DataProtectionProvider属性?我不确定这是否适用,我也在使用identity server,您必须将所有身份验证更改为具有集中令牌服务器。因此,您可以只使用一台服务器进行身份验证,并向其发出cors请求,并相信您收到的令牌是有效的,不必像这样切换到startup类中定义的identity serverI,公共静态IDataProtectionProvider DataProtectionProvider{get;set;}@orhun.begendi您用什么初始化DataProtectionProvider?使用.net core 2对我有效。0@user1015196对对我来说,最好的方法是将密钥持久化到文件系统,并使所有应用程序实例指向完全相同的位置。我也希望如此,但我的应用程序运行在不同的Docker容器中,因此不同的文件系统,因此此解决方案不适用于我。我需要一些东西来保存数据库中的密钥并从中检索。
var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);
var encodedCode = HttpUtility.UrlEncode(token);
services.AddDataProtection().SetApplicationName("same for both apps");