2015-02-08 180 views
1

我試圖通過使用UserManager.GenerateEmailConfirmationTokenUserManager.ConfirmEmail通過電子郵件實現新創建的帳戶收到確認令牌的邀請系統。但是ConfirmEmail方法總是返回false。ASP.NET身份驗證令牌電子郵件始終無效

按在this後我實現了我的MachineKeyDataProtector建議,並在Unity這樣的註冊:

container.RegisterType<IUserTokenProvider<User, Guid>, 
         DataProtectorTokenProvider<User, Guid>>(new InjectionConstructor(new MachineKeyDataProtector("ASP.NET Identity"))); 

我的UserManager注入與IUserTokenProvider這樣的:

public UserManager(IUserStore<User, Guid> store, IUserTokenProvider<User, Guid> userTokenProvider) 
    : base(store) 
{ 
    // Configure validation logic for passwords 
    this.PasswordValidator = new PasswordValidator 
    { 
     RequiredLength = 6, 
     RequireNonLetterOrDigit = false, 
     RequireDigit = true, 
     RequireLowercase = true, 
     RequireUppercase = true, 
    }; 

    this.UserTokenProvider = userTokenProvider; 
} 

我然後封裝在GenerateEmailConfirmationToken方法在擴展方法中:

public static string GenerateUrlForEmailConfirmationToken(this UserManager<User, Guid> userManager, UrlHelper urlHelper, Guid userId) 
{ 
    var verificationCode = userManager.GenerateEmailConfirmationToken(userId); 

    var url = urlHelper.Link(string.Empty, new 
    { 
     controller = "Account", 
     action = "Verify", 
     userId = userId, 
     verificationCode = verificationCode 
    }); 

    return url; 
} 

而且我使用它:

var url = UserManager.GenerateUrlForEmailConfirmationToken(Url, targetUser.Id); 
//injects the url in a ready made html template 
NotificationService.NotifyNewUser(targetUser, url); 

調試GenerateUrlForEmailConfirmationToken我看到MachineKeyDataProtector的保護方法被調用,但是MachineKeyDataProtector的解除是永遠不會的UserManager的ConfirmEmail調用。

如果我改變DI配置到每個請求

container.RegisterType<IUserTokenProvider<User, Guid>, 
         DataProtectorTokenProvider<User, Guid>>(new PerRequestLifetimeManager(), 
         new InjectionConstructor(new MachineKeyDataProtector("ASP.NET Identity"))); 

然後MachineKeyDataProtector的解除被稱爲註冊IUserTokenProvider但trows以下消息一個CryptographicException「加密操作過程中出現錯誤。」

難道這就是驗證總是錯誤的原因嗎?如果是這樣,如何確保調用unprotect方法?通過在這兩種情況下查看對象,UserManager似乎在使用正確的IDataProtector。

任何幫助表示讚賞!

回答

1

在試圖弄清楚爲什麼SignInManager.PasswordSignIn方法總是失敗以及發現問題是由於用戶的SecurityStamp應該已經被設置而沒有被設置。

希望這可以幫助別人。

1

我和你在示例SO帖子中提到的問題一樣。我已經使用它如下。在這種情況下,我已經使用SimpleInjector IOC爲每個Web請求註冊Usermanager

我想你只需要創建新的DataProtectorTokenProvider如果任何dataProtectionProvider不存在。此外,在UserManager構造函數中包含DataProtectorTokenProvider創建將解決該問題。

private static void InitializeUserManager(ApplicationUserManager manager, IAppBuilder app) 
     { 
      manager.UserValidator = new UserValidator<AspNetApplicationUser>(manager) 
      { 
       AllowOnlyAlphanumericUserNames = false, 
       RequireUniqueEmail = true 
      }; 

      // Configure validation logic for passwords 
      manager.PasswordValidator = new PasswordValidator 
      { 
       RequiredLength = 6, 
       RequireNonLetterOrDigit = false, 
       RequireDigit = true, 
       RequireLowercase = true, 
       RequireUppercase = true, 
      }; 

      var dataProtectionProvider = app.GetDataProtectionProvider(); 

      if (dataProtectionProvider != null) 
      { 
       manager.UserTokenProvider = new DataProtectorTokenProvider<AspNetApplicationUser>(
        dataProtectionProvider.Create("ASP.NET Identity")) 
       { 
        TokenLifespan = TimeSpan.FromHours(3) 
       }; 
      } 
     } 

我已經添加了令牌生存時間,但如果不需要,可以將其刪除。

+1

這是正確的。 'DataProtectionTokenProvider'必須是單身人士。其中一個加密密鑰是每次創建對象時生成的guid。 – trailmax 2015-02-08 15:02:37

+0

該示例顯示正在使用默認IDataProtector,這不是按照http://stackoverflow.com/questions/23455579/generating-reset-password-token-does-not-work-in-azure -網站 – JCS 2015-02-08 16:06:56

相關問題