2017-03-02 45 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