Password Reset with SimpleMembership

SimpleMembership is the new security provider that is bundled with ASP.NET MVC 4 when you use the Internet Template to create a new application.  In this article I will demonstrate how to add password reset to your MVC application using SimpleMembership. For this demonstration I will use SimpleSecurity, an open source project that decouples SimpleSecurity from your MVC application. The concepts in this article still apply if you do not use SimpleSecurity and you just want to use SimpleMembership directly.

The basic steps for changing a password when using SimpleMembership is to first generate a unique token that is emailed to the user as a link.  Then the user clicks on the link passing the token in the query string. The user is presented with a web page to enter the new password and when they submit it the token is verified and if it passes the new password is updated in the users membership information. This method of password reset is very flexible since it can be used to just change the password, as well as allow a user to reset their password if they forgot it.

This method of password reset only works if we confirmed the email address during the registration process.  Read this article to see how to add email confirmation to the registration process.  The advantage of using SimpleSecurity is that it is already configured to support email confirmation.  Just as in the email confirmation for registration we will use Postal to send the email for password reset.

To start the password reset process I added an action link to the log-in page for the user to click on.



When the user clicks on the link they are taken to another page which asks them to enter their user name and press the Reset Password button.


Pressing this button sends control to the action PasswordReset.

        [AllowAnonymous]
        [HttpPost]
        public ActionResult ResetPassword(ResetPasswordModel model)
        {
            string emailAddress = WebSecurity.GetEmail(model.UserName);
            if (!string.IsNullOrEmpty(emailAddress))
            {
                string confirmationToken =
                    WebSecurity.GeneratePasswordResetToken(model.UserName);
                dynamic email = new Email("ChngPasswordEmail");
                email.To = emailAddress;
                email.UserName = model.UserName;
                email.ConfirmationToken = confirmationToken;
                email.Send();

                return RedirectToAction("ResetPwStepTwo");
            }

            return RedirectToAction("InvalidUserName");
        }



First this method gets the user email address based on the user name.  Note that in this example I am using SimpleSecurity.WebSecurity instead of WebMatrix.WebData.WebSecurity, which has methods for retrieving the email address. If you are using straight SimpleMembership you will need to develop your own methods to do this, which is described in this article.  If we do not get an email then the user name is invalid and we present the user with a view that lets them know.  If we have a good email we generated the password reset token by calling WebSecurity.GeneratePasswordResetToken with the user name, then create and send the email using Postal. If this is successful we take the user to view that lets them know an email has been sent to them with further instructions for resetting the password.

When the user clicks on the link in the email they are directed to the action ResetPasswordConfirmation.

        [AllowAnonymous]
        public ActionResult ResetPasswordConfirmation(string Id)
        {
            ResetPasswordConfirmModel model = new ResetPasswordConfirmModel() { Token = Id };
            return View(model);
        }



This action gets the token from the query string and puts it in the ResetPasswordConfirmationModel that is passed to the view which allows the user to enter the new password. The new password is entered twice to make sure they entered it correctly. When they submit this information they are taken to the POST version of this action.

       [AllowAnonymous]
        [HttpPost]
        public ActionResult ResetPasswordConfirmation(ResetPasswordConfirmModel model)
        {
            if (WebSecurity.ResetPassword(model.Token, model.NewPassword))
            {
                return RedirectToAction("PasswordResetSuccess");
            }
            return RedirectToAction("PasswordResetFailure");
        }



This action gets the token and new password from the model passed back from the view and calls WebSecurity.ResetPassword to do the actual password reset.  If it is successful the user is presented with a view letting them know that the password was reset and that they should log on with their new password. If it fails they are presented with a view that tells them as such.

That is the fundamentals of adding a password reset to an ASP.NET MVC application with SimpleMembership. If you would like the complete source code for this example you can get it here.


Comments

Popular posts from this blog

Using Claims in ASP.NET Identity

Seeding & Customizing ASP.NET MVC SimpleMembership

Customizing Claims for Authorization in ASP.NET Core 2.0