ASP.NET Core无效密码重置令牌

时间:2017-04-05 21:45:27

标签: c# asp.net-core asp.net-core-identity

我有两个使用相同ASP.NET核心身份后端的服务器。我使用以下代码生成密码重置令牌:

var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);

我通过电子邮件链接发送此令牌。当用户单击该链接时,它们将被带到一个单独的站点,该站点应提供用于更改密码的UI。以下代码处理用户提交令牌及其新密码的密码:

var identityResult = await _userManager.ResetPasswordAsync(applicationUser, code, password);

在第二台服务器上,标识结果始终返回false,因为“无效标记”。

查看源代码,我看到令牌是使用IP地址生成的(所以我理解令牌验证失败的原因)。

我的问题是如何在不同的机器上启用成功的令牌创建/验证?在以前的ASP.NET形式中,我可能会使用共享机器密钥来阻止这些情况。 ASP.NET Core似乎没有类似的概念。根据我的阅读,似乎这可能是使用DataProtection API的场景。不幸的是,我没有看到任何关于如何将其应用于生成重置令牌的示例。

3 个答案:

答案 0 :(得分:4)

您应该在发送令牌之前对其进行编码。你应该这样做:

var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);
var encodedCode = HttpUtility.UrlEncode(token);

对其进行编码后,您必须传递编码的令牌而不是生成的令牌。

答案 1 :(得分:2)

您是否尝试在两个应用程序中将应用程序名称设置为相同的值?

services.AddDataProtection().SetApplicationName("same for both apps");

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview

P.S - 我正在努力解决同样的问题。

答案 2 :(得分:0)

我遇到了类似的问题。它实际上不是2台服务器。它关于身份框架。您可以从usermanager派生,并且可以使用中央管理器覆盖提供者。但我尝试了不同的东西,它的确有效。 首先,ConfirmEmail方法会查看数据库,如果您有一个数据库,那么在具有多个服务器的令牌之间应该不会出现问题。

在你的usermanager中,你应该在你的构造函数中创建dataprovider。

e.Arguments

此外,您应该在数据库表中看到用户的令牌。在这行代码之后。

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

当您在数据库中看到令牌时,请检查电子邮件是否相同。然后单击你的回调网址并更正网址的编码。

使用dataProtectorProvider;

    string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
    var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
    UserManager.EmailService = new EmailService();
    await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");