Blog | G5 Cyber Security

ASP NET Core Identity: Custom Password Reset Email Prompt

TL;DR

The default ASP NET Core Identity password reset form asks for an email address. This guide shows you how to customise it, allowing users to find their account using username instead (or adding other options). It involves creating a custom page and modifying the relevant services.

Customising the Password Reset Form

  1. Create a Custom Page: Add a new Razor page to your project. Name it something descriptive, like ‘ForgotPasswordUsername’.
  2. Model for Username Input: Create a model class to handle username input:
    
    public class ForgotPasswordUsernameInputModel {
        [Required]
        [Display(Name = "Username"])
        public string Username { get; set; }
    }
    
  3. Page Code: In your ‘ForgotPasswordUsername’ page, add the following code:
    
    @page
    @model YourProjectName.Pages.ForgotPasswordUsernameModel
    
    

    Reset Password (Using Username)

  4. Page Model Code: Add the following code to your ‘ForgotPasswordUsername’ page model:
    
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    using System.Threading.Tasks;
    
    namespace YourProjectName.Pages {
        public class ForgotPasswordUsernameModel : PageModel {
            private readonly UserManager _userManager;
            private readonly SignInManager _signInManager; //Needed for redirecting after reset.
    
            public ForgotPasswordUsernameModel(UserManager userManager, SignInManager signInManager) {
                _userManager = userManager;
                _signInManager = signInManager;
            }
    
            [BindProperty]
            public ForgotPasswordUsernameInputModel Input { get; set; }
    
            public async Task OnPostAsync()
            {
                if (!ModelState.IsValid) {
                    return Page();
                }
    
                var user = await _userManager.FindByName(Input.Username);
                if (user == null) {
                    ModelState.AddModelError("", "No account found with that username.");
                    return Page();
                }
    
                // Generate the password reset token
                var code = await _userManager.GeneratePasswordResetTokenAsync(user);
    
                // Construct the callback URL (replace with your actual route)
                var callbackUrl = Url.Page("/ForgotPasswordConfirm", null, "https://yourwebsite.com", null);
                callbackUrl += $”?userId={user.Id}&code={code}";
    
                // Send email (or display a message to copy the link - see step 6)
                await _emailSender.SendEmailAsync(user.Email, "Reset Your Password", callbackUrl);
    
                return RedirectToPage("/ForgotPasswordConfirm?message=CheckYourEmail"); //Redirect to confirmation page.
            }
        }   
    }
  5. Register the Email Sender: Ensure you have an email sender service registered in your Program.cs file (or equivalent startup code). This is crucial for sending the password reset link. If you don’t have one, create a basic implementation or use a third-party service.
    
    builder.Services.AddSingleton();
    
  6. Create ForgotPasswordConfirm Page: Create a new Razor page called ‘ForgotPasswordConfirm’ to display a confirmation message after the reset link is sent.
    
    @page
    @model YourProjectName.Pages.ForgotPasswordConfirmModel
    
    

    Password Reset Link Sent!

    @Model.Message

  7. Configure Services: In your Program.cs file, make sure you’ve configured the Identity services correctly:
    
    builder.Services.AddIdentity()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores(); //Replace YourDbContext with your actual DbContext.
    
  8. Update Navigation (Optional): Add a link to your new ‘ForgotPasswordUsername’ page from your layout or other relevant pages.
Exit mobile version