2015-03-03 54 views
5

我正在使用ASP.NET身份與ClaimsIdentity來驗證我的用戶身份。當用戶通過身份驗證時,屬性User.Identity包含一個ClaimsIdentity實例。未在登錄請求中設置ASP.NET身份

然而,這還不是登錄請求期間的情況:

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 

     var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, false, shouldLockout: false); 
     switch (result) 
     { 
      case SignInStatus.Success: 
       var identity = User.Identity; 

------------> // identity is of type WindowsIdentity <------------ 

       return RedirectToLocal(returnUrl); 

正如你可以看到,即使登錄成功,物業User.Identity尚未設置爲ClaimsIdentity實例。我認爲這是有道理的,這意味着SignInManager不會更新該屬性,所以我們必須等到下一個請求才能看到登錄結果。

不過,我有方法PasswordSignInAsync後做額外的邏輯,所以我需要一種方式來獲得的ClaimsIdentity比如在switch語句的.Success分支。

在考察在調試器中SignInManager,我一看,原來是Microsoft.Owin.Security.AuthenticationManager類型,其具有包含我正在尋找的ClaimsIdentity財產SignInEntry.Item1的。

但是,類型Microsoft.Owin.Security.AuthenticationManager不公開,所以唯一的方法似乎是使用反射的黑客。

有沒有更好的方法?

+1

使用'RedirectToAction'並獲取該操作中的身份?不要返回一個URL,而是返回要重定向到的視圖的名稱。 – 2015-03-03 13:02:44

+0

這是我目前使用的解決方法。但是在登錄操作中不可能獲得'ClaimsIdentity'? – cheeesus 2015-03-03 13:41:16

+1

[顯然不是。](http://stackoverflow.com/a/26739821/3846058) – 2015-03-03 13:45:05

回答

6

我同意PasswordSignInAsync不會將用戶實例作爲out參數返回。如果您查看源代碼,可以看到它使用this.UserManager.FindByNameAsync(userName)通過userName查找用戶,然後使用this.UserManager.CheckPasswordAsync(user, password)驗證密碼,但用戶存儲在本地變量中。

我認爲這應該作爲對SignInManager類的改進提出。

一種可能(且低效的)的解決方法是再次查詢用戶,然後創建以相同的方式對權利要求的身份yourselft SignInManager.SignInAsync作用:

 ApplicationUser user = await UserManager.FindByNameAsync(model.Email); 
     ClaimsIdentity claimsIdentity = await SignInManager.CreateUserIdentityAsync(user); 
2

身份通過AuthenticationResponseGrant屬性公開:

ClaimsIdentity identity = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity;