身份密码重置令牌无效

时间:2014-12-23 09:50:07

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

我正在编写MVC 5并使用Identity 2.0。

现在我正在尝试重置密码。但我总是收到重置密码令牌的“无效令牌”错误。

    public class AccountController : Controller
{
    public UserManager<ApplicationUser> UserManager { get; private set; }

    public AccountController()
        : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
    {
    }

我设置了DataProtectorTokenProvider,

        public AccountController(UserManager<ApplicationUser> userManager)
    {   
        //usermanager config
        userManager.PasswordValidator = new PasswordValidator { RequiredLength = 5 };  
        userManager.EmailService = new IddaaWebSite.Controllers.MemberShip.MemberShipComponents.EmailService(); 

        var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider();
        userManager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<ApplicationUser>(provider.Create("UserToken"))
                                                    as IUserTokenProvider<ApplicationUser, string>;




        UserManager = userManager;

    }

我在发送邮件之前生成密码重置

 [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> ManagePassword(ManageUserViewModel model)
    {
        if (Request.Form["email"] != null)
        {
          var email = Request.Form["email"].ToString();
          var user = UserManager.FindByEmail(email);
          var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
           //mail send
        }
   }

我点击邮件中的链接,我正在获取密码重置令牌并使用

var result = await UserManager.ResetPasswordAsync(model.UserId, model.PasswordToken, model.NewPassword);

结果始终为false,并显示“无效令牌”。 我应该在哪里修理?

4 个答案:

答案 0 :(得分:35)

UserManager.GeneratePasswordResetTokenAsync()经常会返回包含&#39; + {&#39;字符。如果按查询字符串传递参数,则这是原因(&#39; +&#39;字符是URL中查询字符串中的空格)。

尝试将model.PasswordToken中的空格字符替换为&#39; +&#39;字符。

答案 1 :(得分:20)

[HttpPost]
[ValidateAntiForgeryToken]
publicasync Task<ActionResult> ManagePassword(ManageUserViewModel model)
{
    if (Request.Form["email"] != null)
    {
      var email = Request.Form["email"].ToString();
      var user = UserManager.FindByEmail(email);
      var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
       //before send mail
      token = HttpUtility.UrlEncode(token);   
  //mail send

    }
}

密码重置操作解码令牌HttpUtility.UrlDecode(token);

答案 2 :(得分:13)

我发现当数据库中的AspNetUsers表中的用户的SecurityStamp列为NULL时,也会出现“无效令牌”错误。 使用开箱即用的MVC 5 Identity 2.0代码时,SecurityStamp不会为NULL,但是在我们的代码中进行一些自定义的AccountController时,会在SecurityStamp字段中清除值。

答案 3 :(得分:0)

这里的许多答案在发送之前对令牌进行URLEncode以解决令牌(作为基本64位编码的字符串)通常包含“+”字符的事实。解决方案还必须考虑到令牌以'=='结尾。

我正在努力解决这个问题&amp;事实证明,大型组织中的许多用户使用的是Scanmail Trustwave Link Validator(r),它不对称地编码和解码电子邮件链接中的URLEncoded stings(在撰写本文时)。

最简单的方法是使用Mateusz Cisek的答案并发送一个非URLEncoded令牌,只需将空格字符替换回+。在我的情况下,这是在角度SPA中完成的,因此Javascript变为$routeParams.token.replace(/ /g,'+')

这里需要注意的是,如果使用AJAX发送令牌并滚动自己的查询字符串解析算法 - 许多示例将每个参数拆分为'=',这当然不包括'=='在结尾处令牌。使用其中一个正则表达式解决方案或只查找第一个'=',易于解决。