Search code examples
migrationasp.net-core-2.2asp.net-core-3.1asp.net-core-identity

DataProtectorTokenProvider constructor method not found


I've been using two custom token providers with identity in .NET Core 2.2. After migration to 3.1 I'm getting this exception

System.Exception: Could not resolve a service of type 'Microsoft.AspNetCore.Identity.UserManager`1[[App.Domain.Entities.AppUser, App.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' for the parameter 'userManager' of method 'Configure' on type 'App.API.Startup'.
 ---> System.MissingMethodException: Method not found: 'Void Microsoft.AspNetCore.Identity.DataProtectorTokenProvider`1..ctor(Microsoft.AspNetCore.DataProtection.IDataProtectionProvider, Microsoft.Extensions.Options.IOptions`1<Microsoft.AspNetCore.Identity.DataProtectionTokenProviderOptions>)'.
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)

I think its the part in UserManager constructor where they are trying to resolve all token providers.

Here is identity configuration

namespace App.Identity
{
    public static class IdentityExtensions
    {
        public static IServiceCollection AddAppIdentity(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddIdentity<AppUser, AppRole>(options =>
                {
                    options.Password.RequireDigit = true;
                    options.Password.RequireLowercase = true;
                    options.Password.RequireNonAlphanumeric = true;
                    options.Password.RequireUppercase = true;

                    options.Tokens.EmailConfirmationTokenProvider = EmailConfirmationTokenProviderOptions.ProviderName;
            })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders()
            .AddEmailConfirmationTokenProvider()
            .AddMagicLinkLoginTokenProvider();

        return services;
    }

    private static IdentityBuilder AddMagicLinkLoginTokenProvider(this IdentityBuilder builder)
    {
        return builder.AddTokenProvider(
            MagicLinkLoginTokenProviderOptions.ProviderName, 
            typeof(MagicLinkLoginTokenProvider<>).MakeGenericType(builder.UserType)
        );
    }

    private static IdentityBuilder AddEmailConfirmationTokenProvider(this IdentityBuilder builder)
    {
        return builder.AddTokenProvider(
            EmailConfirmationTokenProviderOptions.ProviderName, 
            typeof(EmailConfirmationTokenProvider<>).MakeGenericType(builder.UserType)
        );
    }
}

}

UPDATE:

After some investigation I've noticed that latest DataProtectorTokenProvider has constructor signature which includes ILogger, while mine (Microsoft.AspNetCore.Identity v2.2) only has dataProtectionProvider and options. Am I referencing wrong package or?


Solution

  • Basically the problem was that many of those Microsoft.AspNetCore.* packages are now moved to Microsoft.AspNetCore.App framework, so you remove your Microsoft.AspNetCore.Identity reference and add this to your project

    <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
    </ItemGroup>
    

    After that it should resolve it from shared folder where all the framework dll's are.