Open Closed

How to override IPasswordHasher<> #855


User avatar
0
tim created

We are migrating a lagacy app to ABP framework. The existing user password was encryted with MD5 encrytion.

I am following the post below trying to override the IPasswordHasher<>:

https://andrewlock.net/safely-migrating-passwords-in-asp-net-core-identity-with-a-custom-passwordhasher/

I am updating the Startup.cs file under xxx.HttpApi.Host project:

using ApplicationHelpers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using System;
using System.Text;
using Volo.Abp.Identity;

namespace Bookstore
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<BookstoreHttpApiHostModule>();

            // Replace the existing scoped IPasswordHasher<> implementation
            services.Replace(new ServiceDescriptor(
                serviceType: typeof(IPasswordHasher<Microsoft.AspNetCore.Identity.IdentityUser>),
                implementationType: typeof(Md5PasswordHasher<Microsoft.AspNetCore.Identity.IdentityUser>),
                ServiceLifetime.Scoped));
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            app.InitializeApplication();
        }
    }

    /// <summary>
    /// A drop-in replacement for the standard Identity hasher to be backwards compatible with existing MD5 hashes
    /// New passwords will be hashed with Identity V3
    /// </summary>
    public class Md5PasswordHasher<TUser> : PasswordHasher<TUser> where TUser : class
    {
        public override PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword)
        {
            byte[] decodedHashedPassword = Convert.FromBase64String(hashedPassword);

            // read the format marker from the hashed password
            if (decodedHashedPassword.Length == 0)
            {
                return PasswordVerificationResult.Failed;
            }

            // ASP.NET Core uses 0x00 and 0x01 for v2 and v3
            if (decodedHashedPassword[0] == 0xFF)
            {
                //convert back to string for MD5 encrypt, ignoring first byte
                var storedHash = Encoding.UTF8.GetString(decodedHashedPassword, 1, decodedHashedPassword.Length - 1);

                // md5 hash the provided password
                var md5ProvidedPassword = Cryptography.GeneratePassword(providedPassword);

                if (md5ProvidedPassword == storedHash)
                {
                    // This is an old password hash format - the caller needs to rehash if we're not running in an older compat mode.
                    return PasswordVerificationResult.Success;
                }
                else
                {
                    return PasswordVerificationResult.Failed;
                }
            }

            return base.VerifyHashedPassword(user, hashedPassword, providedPassword);
        }

    }
}

It does not seem like the implimentation gets overrode.

Please let me know how to override IPasswordHasher<>

Thanks, Tim


9 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You need use the Volo.Abp.Identity.IdentityUser as TUser.

    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.PreConfigure<IdentityBuilder>(options =>
        {
            options.Services.Replace(ServiceDescriptor
                .Scoped<IPasswordHasher<Volo.Abp.Identity.IdentityUser>,
                    Md5PasswordHasher<Volo.Abp.Identity.IdentityUser>>());
        });
    }
    
  • User Avatar
    0
    tim created

    Hi Thanks for getting back to you.

    Is this what you meant:

    1. Remove this funtion call from startup.cs // Replace the existing scoped IPasswordHasher<> implementation services.Replace(new ServiceDescriptor( serviceType: typeof(IPasswordHasher<Microsoft.AspNetCore.Identity.IdentityUser>), implementationType: typeof(Md5PasswordHasher<Microsoft.AspNetCore.Identity.IdentityUser>), ServiceLifetime.Scoped));
    2. which project/class to put this method in public override void PreConfigureServices(ServiceConfigurationContext context) { context.Services.PreConfigure<IdentityBuilder>(options => { options.Services.Replace(ServiceDescriptor .Scoped<IPasswordHasher<Volo.Abp.Identity.IdentityUser>, Md5PasswordHasher<Volo.Abp.Identity.IdentityUser>>()); }); }
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer
    1. Remove this funtion call from startup.cs

    Yes.

    2.which project/class to put this method in

    Projects that depend on AbpAccountWebModule, such as web.

  • User Avatar
    0
    tim created

    I just tried on the start-up template (bookstore) and put the code in the Bookstore.Application project and still did not work?

    public class BookstoreApplicationModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure<AbpAutoMapperOptions>(options =>
            {
                options.AddMaps<CROMS3ApplicationModule>();
            });
        }
    
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.PreConfigure<IdentityBuilder>(options =>
            {
                options.Services.Replace(ServiceDescriptor
                    .Scoped<IPasswordHasher<Volo.Abp.Identity.IdentityUser>,
                        Md5PasswordHasher<Volo.Abp.Identity.IdentityUser>>());
            });
        }
    
        ```
    
  • User Avatar
    0
    tim created

    BTW, my solution is an Angular font end with .NET core API backend.

    I did a full text search and I did not find any project that depends on AbpAccountWebModule?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Can you share your Bookstore project to me? liming.ma@volosoft.com

  • User Avatar
    0
    tim created

    It actually worked. Thanks very much!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    : )

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.2.0-preview. Updated on March 13, 2025, 04:08