在使用OWIN请求管道创建ApplicationUserManager时,我遇到了使用依赖项注入创建自定义UserStore的问题.
Background
我正在try 将web应用程序中的用户功能从使用SimpleMembership迁移到新的ASP.网络身份.启动新的MVC 5项目时,单页应用程序的默认实现使用ASP.身份,使用实体框架实现UserStore功能.
在我的例子中,我们已经使用NHibernate作为ORM,并使用ninject来实现工作单元模式,这样每个请求都有一个NHibernate会话,我想让ASP.身份识别与我们现有的框架一起工作.
为此,我创建了一个自定义的UserStore,可以通过注入相关的存储库/nhibernate会话等来创建它.然后可以使用NINJECT将其注入到控制器的构造函数中,而不是使用默认实现的GetOwinContext功能.
为此,我注释掉了Startup的ConfigureAuth(IAppBuilder应用程序)方法中的以下行,该方法默认创建UserManager类:
// app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
相反,我使用了安装Ninject时创建的NinjectWebCommon.网状物常见的Webhost nuget包创建相关绑定.
此实现在某些UserManager操作中运行良好,但在某些操作(如ResetPasswordAsync)中,它会失败,因为未调用默认的ApplicationUserManager实现,因此从未设置UserManager类中的UserTokenProvider:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// 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 in here.
manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is: {0}"
});
manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is: {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
因此,未设置UserTokenProvider.
问题
我想使用OWIN管道,因为Visual Studio的ApplicationUserManager类的默认实现在其创建回调方法中注入了IDataProtectionProvider.然而,我也想使用依赖注入创建我的UserStore,我不知道如何使用依赖注入在这个方法中创建UserStore.
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
// WANT TO CREATE THE USER STORE USING NINJECT DEPENDENCY INJECTION HERE
// var userStore = ...
var manager = new ApplicationUserManager(userStore);
}
我试图通过使用Ninject来绕过这个限制.网状物常见的OwinHost nuget包,并在Startup类中创建内核.
public void ConfigureAuth(IAppBuilder app)
{
// Setup
app.UseNinjectMiddleware(CreateKernel);
}
但是,Ninject.Web.Common.OwinHost不公开其内核,因此我无法使用服务位置模式在创建回调中将值注入到我的自定义UserStore中.
我还try 创建一个Singleton Kernel,并使用app.CreatePerOwinContext(CreateKernel)将其注册到相关委托,以便稍后可以访问该内核,但是当我调用context.Get()时,它只返回null.
Question
如何使用CreatePerOwinContext注册回调函数以创建使用自定义UserStore的自定义UserManager,然后在CREATE回调中使用依赖项注入使用NINJECT创建自定义UserStore,以便我还可以访问owin用来注入用户令牌提供程序的IdentityFactoryOptions?