我使用IdentityServer3进行身份验证。所有用户都存储在Sql DB中,因此我也使用Microsoft.AspNet.Identity
框架进行实际身份验证,出于同样的目的,我创建了自己的ApplicationUserManager
类。
AspNet标识具有集成到OWIN中间件中的IoC功能。它注册了ApplicationUserManager
,如:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
它需要函数委托,它返回ApplicationUserManager
public static ApplicationUserManager
Create(IdentityFactoryOptions<ApplicationUserManager> options,
IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
但是,IdentityServer使用自己的DI框架和(我认为)我们不能使用静态Create()
方法与IdentityServer一起使用ApplicationUserManager
,同样Create()
方法将IdentityFactoryOptions
和IOwinContext
作为参数。
我遵循了这个SO post并且我改变了ApplicationUserManager
的实现以使用构造函数注入
public class ApplicationUserManager : UserManager<ApplicationUser, string>
{
public ApplicationUserManager(ApplicationUserStore store, IdentityFactoryOptions<ApplicationUserManager> options)
: base(store)
{
// Configure validation logic for usernames
UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
UserLockoutEnabledByDefault = true;
DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
MaxFailedAccessAttemptsBeforeLockout = 5;
EmailService = new EmailService();
SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
然后使用IdentityServer自己的DI框架注册所有服务,如下所示
factory.UserService = new Registration<IUserService, UserService>();
factory.Register(new Registration<ApplicationUserManager>());
factory.Register(new Registration<ApplicationUserStore>());
factory.Register(new Registration<IdentityFactoryOptions<ApplicationUserManager>>(resolver => new IdentityFactoryOptions<ApplicationUserManager>
{
DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ASP.NET Identity")
}));
factory.Register(new Registration<ApplicationDbContext>(resolver => new ApplicationDbContext(ApplicationConfig.ConnectionString)));
问题
ApplicationUserManager
的正确方法吗?
IdentiServer的DI框架? DataProtectionProvider
,在构造函数中创建UserTokenProvider
。 IdentityServer如何使用这2个提供程序?IOwinContext
将来,ApplicationUserManager的构造函数不再需要它了
导致OWIN管道出现任何问题? ApplicationUserManager
答案 0 :(得分:3)
这两篇文章有助于解决我的问题
http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/
但是我的ApplicationUserManager
位于单独的类库中,startup.cs
位于Web项目中。类库没有引用Web项目。所以我重构了ApplicationUserManager
构造函数
public ApplicationUserManager(ApplicationUserStore store, IDataProtectionProvider dataProtectionProvider)
: base(store)
{
// other stuff
if (dataProtectionProvider != null)
{
UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("UserToken"));
}
}
并注册了IDataProtectionProvider
DI框架。我没有将Unity用作IoC。我正在使用IdentityServer自己的DI框架。所以我将IDataProtectionProvider
注册为
factory.Register(new Registration<IDataProtectionProvider>(resolver => Startup.DataProtectionProvider));