Search code examples
c#asp.net-coreasp.net-identity

ASP.Net Core Identity ResetPasswordAsync Failed : InvalidToken


I'm trying to create a function that will reset the users password when requested in asp .net core 3.1 using Identity

So far whenever the function GeneratePasswordResetTokenAsync is called it returns the token as expected

// Generate Reset Token.
var token = await userManager.GeneratePasswordResetTokenAsync(appIdentityUser);

CfDJ8OHfQcgoimpKvwzwyqjhuwNuJOOwPXPw2F9wg5t7HNMc+YZbnJn1n8cVwBmq/yYV4edV8wl+p6QHSOv/gtW6yat7iuD9v9dBqTmw+Lie2UY9MDLsMEu+GQWaRlUWEH70FoyGqUUcU1/Tzk6tmBvz8cRPlx2KTnJfVc73e1XMZg69pUk58XRuKzRTgwyw/70aSSy6oh1LgDj4g1OqPRSqsgKaPh1vUnMThYb0GwqovqGZoU37N5COem4RmYFn4uVIEQ==

For testing purposes I am now calling the ResetPasswordAsync within the same method to see if the password will reset

NOTE user is found.

// Find User.
AppIdentityUser user = await userManager.FindByEmailAsync(appIdentityUser.Email);

// Attempt To Reset The Password To someRealL0ngP@ssW0rd
IdentityResult resetPassword = await userManager.ResetPasswordAsync(user, token, "someRealL0ngP@ssW0rd");

Unfortunately I receive this error Failed : InvalidToken

Here is AddIdentity that is in the startup file along with the DbContext.

...
// Create The DbContext.
services.AddDbContext<AppIdentityDbContext>(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("AussieFoods2ULocal"));
});

// Identity User. Plus Password Complexity For Easy Testing.
services.AddIdentity<AppIdentityUser, IdentityRole>(options =>
{
    options.Password.RequireDigit = false;
    options.Password.RequiredLength = 5;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequiredUniqueChars = 0;
    options.Password.RequireUppercase = false;
    options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<AppIdentityDbContext>()
.AddDefaultTokenProviders();

 // Paths For The Identity
 services.ConfigureApplicationCookie(options =>
 {
     options.LoginPath = "/Security/SignIn";
     options.AccessDeniedPath = "/Security/AccessDenided";
 });
    
 services.Configure<DataProtectionTokenProviderOptions>(options =>
 {
      options.TokenLifespan = TimeSpan.FromHours(2);
 });

 services.AddAuthentication();
 ...

I'm not sure if this has anything to do with it, but I did create a custom class that inherits from IdentityUser

public class AppIdentityUser : IdentityUser
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    
    [EmailAddress]
    [Required]
    public override string Email { get => base.Email; set => base.Email = value; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string Suburb { get; set; }
    public string City { get; set; }
    public string PostCode { get; set; }
}

Solution

  • To test your Startup.cs config, I quickly made a new project. The ConfigureServices was the same as yours with services.AddControllersWithViews(); at the end and Configure looks liked below.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
            app.UseDeveloperExceptionPage();
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
    
        app.UseHttpsRedirection();
        app.UseStaticFiles();
    
        app.UseRouting();
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    

    I then created an action to create a user and reset the password. Below is the action to reset the password.

    public async Task ResetPassword()
    {
        var user = await UserManager.FindByEmailAsync("your-email-address@domain.com");
        var token = await UserManager.GeneratePasswordResetTokenAsync(user);
        var result = await UserManager.ResetPasswordAsync(user, token, Guid.NewGuid().ToString());
    }
    

    This returns a successful result.