No IUserTokenProvider is registered when using dep

2019-04-07 23:01发布

问题:

I got an error when my GeneratePasswordResetTokenAsync() method is call. I configured autofac with owin identity.

The error is :

No IUserTokenProvider is registered when using dependency injection

In my sample.web project there is a AutofacConfig.cs file where I register signinmanager and usermanager which I created in sample.repository project.

AutofacConfig.cs

public class AutofacConfig
{
    public static Autofac.IContainer RegisterDependencies()
    {

        var containerBuilder = new ContainerBuilder();

        // REGISTER DEPENDENCIES
        containerBuilder.RegisterType<SampleDataContext>()
                        .As<DbContext>()
                        .InstancePerDependency();
        containerBuilder.RegisterType<UserStore<SampleUser>>()
                        .As<IUserStore<SampleUser>>()
                        .InstancePerRequest();
        containerBuilder.RegisterType<ApplicationUserManager>()
                        .AsSelf()
                        .InstancePerRequest();
        containerBuilder.RegisterType<ApplicationSignInManager>()
                        .AsSelf()
                        .InstancePerRequest();
        containerBuilder.RegisterType<EmailService>();

        containerBuilder.Register<IAuthenticationManager>(c => HttpContext.Current.GetOwinContext().Authentication)
                        .InstancePerRequest();

        var container = containerBuilder.Build();

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        var resolver = new AutofacWebApiDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
        return container;
    }
}

ApplicationUserManager.cs

public class ApplicationUserManager : UserManager<SampleUser>
{
     public ApplicationUserManager(IUserStore<SampleUser> store)
        : base(store)
    {
    }


    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<SampleUser>(context.Get<SampleDataContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<SampleUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 8,
            RequireNonLetterOrDigit = false,
            RequireDigit = false,
            RequireLowercase = false,
            RequireUppercase = false,
        };

        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;

        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug it in here.
        manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<SampleUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<SampleUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });
        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();

        var provider = new DpapiDataProtectionProvider("Sample");

        manager.UserTokenProvider = new DataProtectorTokenProvider<SampleUser>(
        provider.Create("ASP.NET Identity"));
        return manager;
    }
}

回答1:

Remove create() method in ApplicationUserManager.cs class and add that code in ApplicationUserManager class's constructor.

ApplicationUserManager.cs

public class ApplicationUserManager : UserManager<SampleUser>
    {
        public ApplicationUserManager(IUserStore<SampleUser> store, IDataProtectionProvider dataProtectionProvider)
            : base(store)
        {
            // Configure validation logic for usernames
            this.UserValidator = new UserValidator<SampleUser>(this)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };

            // Configure validation logic for passwords
            this.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = false,
                RequireDigit = false,
                RequireLowercase = false,
                RequireUppercase = false,
            };

            // Configure user lockout defaults
            this.UserLockoutEnabledByDefault = true;
            this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
            this.MaxFailedAccessAttemptsBeforeLockout = 5;

            // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
            // You can write your own provider and plug it in here.
            this.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<SampleUser>
            {
                MessageFormat = "Your security code is {0}"
            });
            this.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<SampleUser>
            {
                Subject = "Security Code",
                BodyFormat = "Your security code is {0}"
            });
            this.EmailService = new EmailService();
            this.SmsService = new SmsService();

           // var dataProtectionProvider = Startup.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                IDataProtector dataProtector = dataProtectionProvider.Create("ASP.NET Identity");

                this.UserTokenProvider = new DataProtectorTokenProvider<SampleUser>(dataProtector);
            }
        }


    }

register DataProtectionProvider in AutofacConfig.cs file

containerBuilder.Register<IDataProtectionProvider>(c =>  Startup.DataProtectionProvider).InstancePerRequest();

Resolve ApplicationUSerManager class in Startup.cs class

public partial class Startup
     {

        public static IDataProtectionProvider DataProtectionProvider { get; private set; }
        public void ConfigureAuth(IAppBuilder app)
        {
            // add this assignment
            DataProtectionProvider = app.GetDataProtectionProvider();
             // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(SampleDataContext.Create);

            app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
             app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationSignInManager>());

         }
     }

just got solution from here it is very helpful article