Picture of a lake in Canada

ASP.NET MVC 3 - C# Password Reset

February 28, 2011

This code allows users to reset the passwords if they have forgotten them, the ASP.NET membership provider generates a random password which is presented to them on the page after the reset link has been clicked.

The URL parameter looks like this:

?username=username&reset=24-C7-27-F8-5D-19-45-06-13-ED-CB-D7-F2-1E-48-7C

The “-” could quite easily be removed using a regular expression if you don’t like them!

Any comments or criticism welcome, I would like to improve my programming skills and techniques! (see code below)

//Model Class    
public class ResetPasswordModel
{
    [Required]
    [Display(Name = "Username")]
    public string Username { get; set; }

    public void ResetPassword(string username)
    {
       MembershipUser currentUser = Membership.GetUser(username);
       string password = currentUser.ResetPassword();
       SendEmail.SendResetEmail(currentUser);
    }
}

//Send Email Method
public static void SendResetEmail(System.Web.Security.MembershipUser user)
{
     MailMessage email = new MailMessage();

     email.From = new MailAddress("[email protected]");
     email.To.Add(new MailAddress(user.Email));
        
     email.Subject = "Password Reset";
     email.IsBodyHtml = true;
     string link = "http://www.example.com/Account/ResetPassword/?username="+ user.UserName +"&reset=" + HashResetParams(user.UserName, user.ProviderUserKey.ToString());
     email.Body = "
"+ user.UserName + " please click the following link to reset your password: " + link + "

";
     email.Body += "
If you did not request a password reset you do not need to take any action.

";

     SmtpClient smtpClient = new SmtpClient();

     smtpClient.Send(email);
 }

//Method to hash parameters to generate the Reset URL
public static string HashResetParams(string username, string guid)
{

     byte[] bytesofLink = System.Text.Encoding.UTF8.GetBytes(username + guid);
     System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
     string HashParams = BitConverter.ToString(md5.ComputeHash(bytesofLink));

     return HashParams;
}

//Controllers for the reset page
public ActionResult ResetPassword(string reset, string username)
 {
      if ((reset != null) && (username != null))
      {
          MembershipUser currentUser = Membership.GetUser(username);
          if (SendEmail.HashResetParams(currentUser.UserName, currentUser.ProviderUserKey.ToString()) == reset)
          {
              ViewBag.newPass = currentUser.ResetPassword();
              ViewBag.userName = username;
              return View("ResetPasswordSuccess");
           }
      }

      return View();
}

[HttpPost]
public ActionResult ResetPassword(ResetPasswordModel Model)
{
    MembershipUser currentUser = Membership.GetUser(Model.Username);
            
    if (ModelState.IsValid)
    {
         SendEmail.SendResetEmail(currentUser);
    }
    return View();
}
comments powered by Disqus