29

Microsoft is coming up with a new Membership system called ASP.NET Identity (also the default in ASP.NET MVC 5). I found the sample project, but this is not implemented a password reset.

On password reset topic just found this Article: Implementing User Confirmation and Password Reset with One ASP.NET Identity – Pain or Pleasure, not help for me, because do not use the built-in password recovery.

As I was looking at the options, as I think we need to generate a reset token, which I will send to the user. The user can set then the new password using the token, overwriting the old one.

I found the IdentityManager.Passwords.GenerateResetPasswordToken / IdentityManager.Passwords.GenerateResetPasswordTokenAsync(string tokenId, string userName, validUntilUtc), but I could not figure out what it might mean the tokenId parameter.

How do I implement the Password Reset in ASP.NET with MVC 5.0?

5
  • 1
    Thank you for your help and support! My problem is that method (IdentityManager.Passwords.GenerateResetPasswordToken) described could not find any information anywhere, so I can not use it. But anyway, I will soon make up for the missing information and i will include valid code! Commented Sep 25, 2013 at 15:12
  • so what's the difference between IdentityManager and UserManager? When I created a new project the AccountController used UserManager. Commented Oct 31, 2013 at 16:59
  • 1
    I've moved your answer to your answer, instead of it being in the question. Commented Mar 19, 2014 at 13:51
  • 2
    See my tutorial Account Confirmation and Password Recovery with ASP.NET Identity asp.net/identity/overview/features-api/… Commented May 16, 2014 at 21:25
  • link does not work anymore... Commented Jul 19, 2017 at 18:34

2 Answers 2

9

I get it: The tokenid is a freely chosen identity, which identifies a password option. For example,

1. looks like the password recovery process, step 1 (it is based on: https://stackoverflow.com/a/698879/208922)

[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 And then when the user enters the token and the new password:

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

Skeleton proposal to sample project on github, if anyone needs it may be tested.The E-mail sending not yet written, possibly with the addition soon.

Sign up to request clarification or add additional context in comments.

4 Comments

What is IdentityManager and where does it come from ?!
I would also like to know what is IdentityManager. Please Help.
@stuartdotnet The ASP.NET Identity system is designed to replace the previous ASP.NET Membership and Simple Membership systems. asp.net/identity
I can't use IdentityManager too, neither find wth the method GenerateResetPasswordTokenAsync comes from.
5

Seems like a lot of trouble... What advantage does the above give over:

  1. the user clicking a 'Recover Account' link
  2. this sends an 64 byte encoded string of a datetime ticks value (call it psuedo-hash) in an email
  3. click the link back in the email to a controller/action route that
  4. matches email and it's source server to psuedo-hash, decrypts the psuedo-hash, validates the time since sent and
  5. offers a View for the user to set a new password
  6. with a valid password, the code removes the old user password and assigns the new.
  7. Once complete, successful or not, delete the psuedo-hash.

With this flow, at no time do you EVER send a password out of your domain.

Please, anyone, prove to me how this is any less secure.

1 Comment

I actually wanted to remove this answer, but left it up to see the folly in it's thought process. 1. The Asp.Net password reset process is standardized and proven. 2. There are no passwords sent out over the wire. 3. Why reinvent the wheel? 4. Once you understand how password recovery works in Identity 2.1+, it's so simple, why would you want to bother with developing anything else - including the time needed to design and test your process thoroughly enough to pass security muster. Don't do what my answer suggests - it's just a time waster

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.