在尝试手动创建DataProtectionProvider
时,我偶然发现了Microsoft对DpapiDataProtectionProvider
的文档,其中写道:
用于提供从数据保护API当您应用程序不是由ASP.NET托管的,并且所有进程都以相同的域标识。
突然出现了一个问题:当您的应用程序由ASP.NET托管时,最佳选择是什么
进一步搜索,似乎最好的选择是从OWIN获得DataProtectionProvider
。这可以在Startup配置中完成,在该配置中您有IAppBuilder
,使用位于Microsoft.Owin.Security.DataProtection
命名空间中的AppBuilderExtensions
可以调用app.GetDataProtectionProvider()
。
到目前为止,我很满意。但是,现在您想要在类的构造函数(例如UserManager
)中注入DataProtectionProvider
。我看到一个建议,将DataProtectionProvider
存储在静态属性中,然后在需要的地方使用它,但这似乎是一个错误的解决方案。
我认为类似于以下代码的解决方案是合适的(使用ninject容器):
kernel.Bind<IDataProtectionProvider>()
// beware, method .GetDataProtectionProvider() is fictional
.ToMethod(c => HttpContext.Current.GetOwinContext().GetDataProtectionProvider())
.InRequestScope();
有一个演练,告诉如何向Autofac注册DataProtectionProvider。
builder.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest();
您也可以使用Unity通过以下行实现这一点:
container.RegisterType<IDataProtectionProvider>(new InjectionFactory(c => app.GetDataProtectionProvider()));
所在的集装箱
var container = new UnityContainer();
这将允许您在构造函数中使用DataProtectionProvider,如下所示。
public ApplicationUserManager(IUserStore<ApplicationUser> store, IIdentityMessageService emailService, IDataProtectionProvider dataProtectionProvider)
我更喜欢这种方法,而不是这篇博客文章中提到的方法https://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/,因为它允许您在单独的库中使用DataProtectionProvider的类(如果您愿意的话),而且它更干净。