Is this really the version you are looking for? Kentico Xperience 12 Service Pack Documentation is no longer updated. Use the switcher in the header to choose your product version.
Password reset features are an important part of any website that allows visitors to register accounts and sign in. Such features are commonly used as a recovery mechanism by users who forget their password.
When developing MVC websites, you can implement email-based password reset functionality using the Kentico.Membership API (provided as part of the Kentico.AspNet.Mvc integration package) in combination with the standard ASP.NET Identity (opens in a new tab) API.
To learn how to set up password reset functionality for the Kentico administration interface, see:
Before you start working on password reset functionality, you need to perform the following:
The built-in password features of Kentico are NOT supported by default when resetting passwords on MVC sites. This includes:
Password reset email templates. The content of emails sent to users during the password reset process is fully controlled by the MVC application.
Password reset settings configured in Settings -> Security & Membership -> Passwords -> Password reset.
Manual resetting of passwords through the Kentico administration is possible, even for users of MVC sites. Administrators can change passwords by editing users in the Users application on the Password tab.
Password storage format
One setting that does apply to user passwords on MVC sites is the Password format, which you can configure within Kentico in Settings -> Security & Membership -> Passwords. See Setting the user password format for more information. The integration API ensures that any passwords submitted by users on your MVC website are stored in the format configured for the Kentico application.
If your Kentico application uses custom salt values when generating password hashes, you also need to set the same values for the MVC application. Check the appSettings section of your Kentico application's web.config for the following keys:
If either of the keys is present, copy them to the web.config of your MVC project.
To allow users to reset their passwords on your MVC site, you need to develop the required controllers and views using the membership integration API.
Configuring the password reset email settings
The password reset solution utilizes emails that are sent by the Kentico API's email engine. Configure the email settings through the administration interface of the connected Kentico application:
Create a new controller class in your MVC project or edit an existing one.
Prepare a property that gets an instance of the Kentico.Membership.UserManager class for the current request – call HttpContext.GetOwinContext().Get<UserManager>().
Implement two actions to allow users to submit password reset requests:
Perform the following steps within the POST action:
Add another action that handles the password reset requests – validate the token and display a password reset form. Call the UserManager.VerifyUserToken method to verify the validity of the password reset token.
The VerifyUserToken method requires the following parameters:
Add a POST action that accepts the input of the password reset form. Call the UserManager.ResetPassword method to set new passwords for users.
You need to supply the user ID and token from the password reset request and the new password as the method's parameters.
using System;
using System.Web;
using System.Web.Mvc;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Kentico.Membership;
namespace LearningKit.Controllers
{
public class PasswordResetController : Controller
{
/// <summary>
/// Provides access to the Kentico.Membership.UserManager instance.
/// </summary>
public UserManager UserManager
{
get
{
return HttpContext.GetOwinContext().Get<UserManager>();
}
}
/// <summary>
/// Allows visitors to submit their email address and request a password reset.
/// </summary>
public ActionResult RequestPasswordReset()
{
return View();
}
/// <summary>
/// Generates a password reset request for the specified email address.
/// Accepts the email address posted via the RequestPasswordResetViewModel.
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> RequestPasswordReset(RequestPasswordResetViewModel model)
{
// Validates the received email address based on the view model
if (!ModelState.IsValid)
{
return View(model);
}
// Gets the user entity for the specified email address
Kentico.Membership.User user = UserManager.FindByEmail(model.Email);
if (user != null)
{
// Generates a password reset token for the user
string token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
// Prepares the URL of the password reset link (targets the "ResetPassword" action)
// Fill in the name of your controller
string resetUrl = Url.Action("ResetPassword", "PasswordReset", new { userId = user.Id, token }, Request.Url.Scheme);
// Creates and sends the password reset email to the user's address
await UserManager.SendEmailAsync(user.Id, "Password reset request",
String.Format("To reset your account's password, click <a href=\"{0}\">here</a>", resetUrl));
}
// Displays a view asking the visitor to check their email and click the password reset link
return View("CheckYourEmail");
}
/// <summary>
/// Handles the links that users click in password reset emails.
/// If the request parameters are valid, displays a form where users can reset their password.
/// </summary>
public ActionResult ResetPassword(int? userId, string token)
{
try
{
// Verifies the parameters of the password reset request
// True if the token is valid for the specified user, false if the token is invalid or has expired
// By default, the generated tokens are single-use and expire in 1 day
if (UserManager.VerifyUserToken(userId.Value, "ResetPassword", token))
{
// If the password request is valid, displays the password reset form
var model = new ResetPasswordViewModel
{
UserId = userId.Value,
Token = token
};
return View(model);
}
// If the password request is invalid, returns a view informing the user
return View("ResetPasswordInvalid");
}
catch (InvalidOperationException)
{
// An InvalidOperationException occurs if a user with the given ID is not found
// Returns a view informing the user that the password reset request is not valid
return View("ResetPasswordInvalid");
}
}
/// <summary>
/// Resets the user's password based on the posted data.
/// Accepts the user ID, password reset token and the new password via the ResetPasswordViewModel.
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult ResetPassword(ResetPasswordViewModel model)
{
// Validates the received password data based on the view model
if (!ModelState.IsValid)
{
return View(model);
}
try
{
// Changes the user's password if the provided reset token is valid
if (UserManager.ResetPassword(model.UserId, model.Token, model.Password).Succeeded)
{
// If the password change was successful, displays a view informing the user
return View("ResetPasswordSucceeded");
}
// Occurs if the reset token is invalid
// Returns a view informing the user that the password reset failed
return View("ResetPasswordInvalid");
}
catch (InvalidOperationException)
{
// An InvalidOperationException occurs if a user with the given ID is not found
// Returns a view informing the user that the password reset failed
return View("ResetPasswordInvalid");
}
}
}
}We recommend creating view models for your password reset actions and input forms:
For the reset request form, the view model needs to validate and transfer the email address value.
For the password reset form, the view model must contain the user ID, reset token and the new password.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class ResetPasswordViewModel
{
public int UserId
{
get;
set;
}
public string Token
{
get;
set;
}
[DataType(DataType.Password)]
[Required(ErrorMessage = "The Password cannot be empty.")]
[DisplayName("Password")]
[MaxLength(100, ErrorMessage = "The Password cannot be longer than 100 characters.")]
public string Password
{
get;
set;
}
[DataType(DataType.Password)]
[DisplayName("Password confirmation")]
[MaxLength(100, ErrorMessage = "The Password cannot be longer than 100 characters.")]
[Compare("Password", ErrorMessage = "The entered passwords do not match.")]
public string PasswordConfirmation
{
get;
set;
}
}Design the user interface for the password reset functionality on your website:
Users can now reset their passwords on your MVC site. When a user clicks the password reset button or link and submits their email address, the system sends them an email. The email contains a link (single-use with a 1-day expiration by default) that sends the user to a password reset form, where they can set a new password. The password reset form only works for users who access the URL with a valid token parameter.