2017-03-02 56 views
2

我正在使用IdentityServer3进行身份验证。所有用户都存储在Sql DB中,因此我也使用Microsoft.AspNet.Identity框架进行实际身份验证,并为了同样的目的创建了我自己的ApplicationUserManager类。如何使用IdentityServer DI框架注册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()方法,以rgister ApplicationUserManager与IdentityServer,Create()方法需要IdentityFactoryOptionsIOwinContext作为参数。

我跟着这个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))); 

问题

  1. 这是一个正确的方式注册ApplicationUserManager与 IdentiServer的DI框架?
  2. 我在注册时创建了DataProtectionProvider,在构造函数中创建了UserTokenProvider。 IdentityServer如何使用这2个提供者?
  3. 请注意,我没有注册IOwinContext因为 ApplicationUserManager的构造函数不再需要它,将 导致任何问题的OWIN管道?
  4. 什么是ApplicationUserManager理想的注册模式?
+1

这将有助于:http://tech.trailmax。发布我的问题后,信息/ 2014/09/ASPNET身份和-IOC容器注册/ – trailmax

+0

@trailmax,我读了你的文章http://tech.trailmax.info/2014/06/asp-net-identity- and-cryptographicexception-when-running-your-site-on-microsoft-azure-web-sites /因为我也遇到了CryptographicException。所以我根据建议在Startup.cs中将IDataProtectionProvider注册为“internal static”。但是我'ApplicationUserManager'是在不同的装配,所以我不得不注册'IDataProtectionProvider'为'factory.Register(新注册(旋=> Startup.DataProtectionProvider));' – LP13

回答

2

这两篇文章有助于解决我的问题

http://tech.trailmax.info/2014/06/asp-net-identity-and-cryptographicexception-when-running-your-site-on-microsoft-azure-web-sites/

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")); 
     } 
    } 

,并与DI框架注册IDataProtectionProvider。我不使用Unity作为IoC。我正在使用IdentityServer自己的DI框架。所以我注册IDataProtectionProvider

factory.Register(new Registration<IDataProtectionProvider>(resolver => Startup.DataProtectionProvider)); 
+0

啊,美好的旧项目的分离,让你每次!很好,你有它排序! – trailmax