Starts in:
2 DAYS
10 HRS
20 MIN
49 SEC
Starts in:
2 D
10 H
20 M
49 S
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.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06