Подтвердить что ты не робот

Как реализовать пароль reset с помощью ASP.NET Identity для ASP.NET MVC 5.0?

Microsoft придумала новую систему членства под названием "Идентификация ASP.NET" (также по умолчанию в ASP.NET MVC 5). Я нашел образец проекта, но это не реализовано с паролем reset.

В пароле reset тема только что нашла эту статью: Внедрение пользовательского подтверждения и пароля reset с одним идентификатором ASP.NET - боль или удовольствие, а не помощь для меня, потому что не используйте встроенное восстановление пароля.

Поскольку я рассматривал варианты, так как мне кажется, нам нужно сгенерировать токен reset, который я вышлю пользователю. Пользователь может установить новый пароль с помощью токена, перезаписав старый.

Я нашел IdentityManager.Passwords.GenerateResetPasswordToken/IdentityManager.Passwords.GenerateResetPasswordTokenAsync(string tokenId, string userName, validUntilUtc), но я не мог понять, что это может означать параметр tokenId.

Как реализовать пароль reset в ASP.NET с MVC 5.0?

4b9b3361

Ответ 1

Я понимаю: токенид является свободно выбранным идентификатором, который идентифицирует пароль. Например,

1. выглядит как процесс восстановления пароля, шаг 1 (он основан на: fooobar.com/questions/2688/...)

[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
//[RecaptchaControlMvc.CaptchaValidator]
public virtual async Task<ActionResult> ResetPassword(
                                              ResetPasswordViewModel rpvm)
{
    string message = null;
    //the token is valid for one day
    var until = DateTime.Now.AddDays(1);
    //We find the user, as the token can not generate the e-mail address, 
    //but the name should be.
    var db = new Context();
    var user = db.Users.SingleOrDefault(x=>x.Email == rpvm.Email);

    var token = new StringBuilder();

    //Prepare a 10-character random text
    using (RNGCryptoServiceProvider 
                        rngCsp = new RNGCryptoServiceProvider())
    {
        var data = new byte[4];
        for (int i = 0; i < 10; i++)
        {
            //filled with an array of random numbers
            rngCsp.GetBytes(data);
            //this is converted into a character from A to Z
            var randomchar = Convert.ToChar(
                                      //produce a random number 
                                      //between 0 and 25
                                      BitConverter.ToUInt32(data, 0) % 26 
                                      //Convert.ToInt32('A')==65
                                      + 65
                             );
            token.Append(randomchar);
        }
    }
    //This will be the password change identifier 
    //that the user will be sent out
    var tokenid = token.ToString();

    if (null!=user)
    {
        //Generating a token
        var result = await IdentityManager
                                .Passwords
                                .GenerateResetPasswordTokenAsync(
                                              tokenid, 
                                              user.UserName, 
                                              until
                           );

        if (result.Success)
        {
            //send the email
            ...
        }
    }
    message = 
        "We have sent a password reset request if the email is verified.";
    return RedirectToAction(
                   MVC.Account.ResetPasswordWithToken(
                               token: string.Empty, 
                               message: message
                   )
           );
}

2 И затем, когда пользователь вводит токен и новый пароль:

[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
//[RecaptchaControlMvc.CaptchaValidator]
public virtual async Task<ActionResult> ResetPasswordWithToken(
                                            ResetPasswordWithTokenViewModel 
                                                        rpwtvm
                                        )
{
    if (ModelState.IsValid)
    {
        string message = null;
        //reset the password
        var result = await IdentityManager.Passwords.ResetPasswordAsync(
                                                   rpwtvm.Token, 
                                                   rpwtvm.Password
                           );
        if (result.Success)
        { 
            message = "the password has been reset.";
            return RedirectToAction(
                        MVC.Account.ResetPasswordCompleted(message: message)
                   );
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(MVC.Account.ResetPasswordWithToken(rpwtvm));
}

Предложение скелета до образец проекта на github, если кому-то это нужно, он может быть протестирован. Посылка электронной почты еще не написана, возможно, с добавлением в ближайшее время.

Ответ 2

Кажется, много неприятностей... Какое преимущество имеет вышеизложенное:

  • пользователь, нажимая ссылку "Восстановить учетную запись"
  • это отправляет 64-байтную кодированную строку значения datetime ticks (вызывают его psuedo-hash) в электронном письме
  • щелкните ссылку в письме на контроллер/маршрут действий, который
  • соответствует электронной почте, а исходный сервер - psuedo-hash, расшифровывает psuedo-hash, проверяет время с момента отправки и
  • предлагает пользователю возможность установить новый пароль.
  • с допустимым паролем, код удаляет старый пароль пользователя и назначает новый.
  • После завершения, успешного или нет, удалите psuedo-hash.

С помощью этого потока вы никогда не отправляете пароль из своего домена.

Пожалуйста, кто-нибудь, докажите мне, как это менее безопасно.