将自定义 UserManager 注入 Controller Net Core 2.1

Posted

技术标签:

【中文标题】将自定义 UserManager 注入 Controller Net Core 2.1【英文标题】:Inject Custom UserManager To Controller Net Core 2.1 【发布时间】:2019-01-08 17:18:11 【问题描述】:

我在尝试将我的 UserManager 注入我的控制器时遇到问题。

这是我的自定义 UserManager:

  public class ApplicationUserManager : UserManager<ApplicationUser>
    

        public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher,
             IEnumerable<IUserValidator<ApplicationUser>> userValidators,
             IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors,
             IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger)
             : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
            

            


        public async Task<ApplicationUser> FindAsync(string id, string password)
        
            ApplicationUser user = await FindByIdAsync(id);
            if (user == null)
            
                return null;
            
            return await CheckPasswordAsync(user, password) ? user : null;
        
    

这是我的 Startup.cs

public IServiceProvider ConfigureServices(IServiceCollection services)
        
            services.ConfigureCors();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
                
                    options.TokenValidationParameters = new TokenValidationParameters
                    
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = Configuration["Jwt:Issuer"],
                        ValidAudience = Configuration["Jwt:Issuer"],
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                    ;
                );
            // Add framework services.
            services.AddMvc();
            services.AddScoped<ApplicationUserManager>();

            var builder = new ContainerBuilder();
            builder.Populate(services);

            // Registering MongoContext. 
            builder.RegisterType<MongoContext>().AsImplementedInterfaces<MongoContext, ConcreteReflectionActivatorData>().SingleInstance();
            //builder.RegisterType<MongoContext>().As<IMongoContext>();

            //Registering ApplicationUserManager. 

   builder.RegisterType<ApplicationUserManager>().As<UserManager<ApplicationUser>>().SingleInstance();
        //builder.RegisterType<ApplicationUserManager>().As<ApplicationUserManager>().SingleInstance();

其中两条重要的行是:builder.RegisterType ApplicationUserManager ().As UserManager ApplicationUser ().SingleInstance();builder.RegisterType ApplicationUserManager ()。作为ApplicationUserManager().SingleInstance;

我的控制器:(我用这 2 个构造函数对其进行了测试,得到了同样的错误)

 public AccountController(ApplicationUserManager applicationUserManager)
        
            this.applicationUserManager = applicationUserManager;
        
        public AccountController(UserManager<ApplicationUser> userManager)
        
            this.userManager = userManager;
        

最后是错误:

Autofac.Core.DependencyResolutionException: 没有构造函数 发现与 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 类型 'VotNetMon.ApplicationUserManager' 可以用可用的调用 服务和参数:无法解析参数 'Microsoft.AspNetCore.Identity.IUserStore1[VotNetMon.Entities.ApplicationUser] store' of constructor 'Void .ctor(Microsoft.AspNetCore.Identity.IUserStore1[VotNetMon.Entities.ApplicationUser], Microsoft.Extensions.Options.IOptions1[Microsoft.AspNetCore.Identity.IdentityOptions], Microsoft.AspNetCore.Identity.IPasswordHasher1[VotNetMon.Entities.ApplicationUser], System.Collections.Generic.IEnumerable1[Microsoft.AspNetCore.Identity.IUserValidator1[VotNetMon.Entities.ApplicationUser]], System.Collections.Generic.IEnumerable1[Microsoft.AspNetCore.Identity.IPasswordValidator1[VotNetMon.Entities.ApplicationUser]], Microsoft.AspNetCore.Identity.ILookupNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber, System.IServiceProvider, Microsoft.Extensions.Logging.ILogger1[Microsoft.AspNetCore.Identity.UserManager1[VotNetMon.Entities.ApplicationUser]])'。 在 Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext 上下文,IEnumerable1 parameters) at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable1 参数)在 Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 参数)

提前致谢

【问题讨论】:

【参考方案1】:

正如错误所说,您必须注册 IUserStore 和其他通常由 AspNetIdentity 的扩展方法注册的依赖项。

services.AddIdentity<ApplicationUser, IdentityRole>();

请注意,这也会添加 cookie 身份验证,因为这是 asp.net identity 所做的。如果你坚持用 autofac 做,什么是完全合法的,你应该看看 here 哪些类必须注册。

如果您想同时使用 identity 和 jwt,here 是一个很好的教程,可以指导您完成它。

无直接关系:

请始终使用接口,不要注入实现,因此不要配置您的容器来解析实现。 有一种新方法可以同时使用 autofac 和 microsoft 的 ioc,这是首选。你可以找到一个例子here。这是 asp.net core >= 2.0 想要的方式。

【讨论】:

非常感谢。没有 autofac,本教程工作正常。但我没有看到我必须注册哪些类才能与 autofac 一起使用。 (IStore, IServiceCollection ... ??) 我把它链接在我的答案中,就是这个链接:github.com/aspnet/Identity/blob/… 是来自微软的源代码。

以上是关于将自定义 UserManager 注入 Controller Net Core 2.1的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义 Executor 注入到 play 应用程序中?

将自定义标签注入 Java 客户端的默认 jmx Prometheus 指标

如何将自定义代码注入 Swift 中内置类的每个实例化?

如何将 UserManager 注入 ASP.NET Core 2.0 中的另一个服务

ASP.NET Core 标识不注入 UserManager<ApplicationUser>

Spring接口编程_设值注入和构造注入