2017-04-14 152 views
0

当用户在输入新密码后尝试在重置密码屏幕上重置密码时,我们会收到无效令牌错误消息。通常这对每个人都适用,即使是像#这样的特殊字符。我们现在有一种情况,有人在复位pw屏幕上将新密码放入*中,只是因为这个特殊字符而得到这个错误信息。ASP.Net密码重置时的密码重置为“无效令牌”,密码为

我已经尝试了数小时的研究来找到解决方案,为什么发生这种情况,但没有运气。我找到了this solution here,它在用户名中有特殊字符的问题,但我们没有这个问题。密码中的特殊字符只有一个问题。由于我们已经在生产,我们不能在密码中禁止该字符。

有人有线索?

生成令牌控制方法:

[HttpPost] 
[AllowAnonymous] 
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var user = await _userManager.FindByNameAsync(model.Email.ToLower()); 
     if (user == null || !(await _userManager.IsEmailConfirmedAsync(user.UserName))) 
     { 
      // Don't reveal that the user does not exist or is not confirmed 
      return View("ForgotPasswordConfirmation"); 
     } 

     // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 
     // Send an email with this link 
     var code = await _userManager.GeneratePasswordResetTokenAsync(user.UserName); 
     code = HttpUtility.UrlEncode(code); 
     var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.UserName, code = code }, protocol: Request.Url.Scheme); 

     await _emailService.CreateResetPasswordEmailAsync(user, callbackUrl); 
     return RedirectToAction("ForgotPasswordConfirmation", "Account"); 
    } 

    // If we got this far, something failed, redisplay form 
    return View(model); 
} 

重置密码控制器的方法:

[HttpPost] 
[AllowAnonymous] 
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(model); 
    } 

    var user = await _userManager.FindByNameAsync(model.Email.ToLower()); 
    if (user == null) 
    { 
     // Don't reveal that the user does not exist 
     return RedirectToAction("ResetPasswordConfirmation", "Account"); 
    } 

    var result = await _userManager.ResetPasswordAsync(user.UserName, HttpUtility.UrlDecode(model.Code), model.Password); 
    if (result.Succeeded) 
    { 
     return RedirectToAction("ResetPasswordConfirmation", "Account"); 
    } 

    AddErrors(result); 
    return View(); 
} 
+0

你是如何generaing令牌?令牌不包含与密码有关的任何内容,因此您看到的错误与您声明的问题相关的方式非常不清楚。 – DavidG

+0

我已经添加了代码片段 – Hypi

+0

您在哪一行看到异常发生? – DavidG

回答

1

的问题是,你是双编码重置令牌。在这里:

var code = await _userManager.GeneratePasswordResetTokenAsync(user.UserName); 
code = HttpUtility.UrlEncode(code); //<--problem is this line 
var callbackUrl = Url.Action("ResetPassword", "Account", 
    new { userId = user.UserName, code = code }, protocol: Request.Url.Scheme); 

你编码的令牌,然后Url.Action会再次这样做。所以解决方法是不要手动编码,让MVC为你处理 - 只需在这里删除第二行。

此外,在另一端,现在有没有必要再进行解码,所以你的代码会出现:

var result = await _userManager.ResetPasswordAsync(user.UserName, 
    model.Code, model.Password); 
+0

谢谢@DavidG :) – Hypi