2016-10-17 16 views
1

我的背景下用戶用戶標識與本地用戶商店和oauth提供商之間的關係如何?

我試圖創建一個自定義的用戶/角色存儲ASP.NET身份

背景

這裏有幾個問題在SO有關獲取用戶ID當使用ASP.NET身份。他們中的大多數都是圍繞解析NameIdentifier聲明來解決的。

但是,他們中的大多數人似乎錯過了一個進口點。使用OAuth時,NameIdentifier似乎指向OAuth提供商返回的身份。

這可以通過在驗證完成後在AccountController中設置一個斷點來觀察。

我的問題

如果你看看UserStore你可以看到,GetUserIdAsync將返回IdentityUser對象,它是從數據庫內部的id Id。迄今爲止都很好。

但是,如果你看看UserManager它得到了下面的代碼:

/// <summary> 
/// Returns the User ID claim value if present otherwise returns null. 
/// </summary> 
/// <param name="principal">The <see cref="T:System.Security.Claims.ClaimsPrincipal" /> instance.</param> 
/// <returns>The User ID claim value, or null if the claim is not present.</returns> 
/// <remarks>The User ID claim is identified by <see cref="F:System.Security.Claims.ClaimTypes.NameIdentifier" />.</remarks> 
public virtual string GetUserId(ClaimsPrincipal principal) 
{ 
    if (principal == null) 
    throw new ArgumentNullException("principal"); 
    return principal.FindFirstValue(this.Options.ClaimsIdentity.UserIdClaimType); 
} 

..這看起來第一峯就好了。但是,如果您查看UserIdClaimType的常數值,則它與ClaimTypes.NameIdentifier相同。因此它將獲取oauth用戶標識。這不會工作,由於上述問題

代碼:

//this returns the oauth id, can't be used to work with the application user 
var id = await _userManager.GetUserIdAsync(currentClaimPrincipal); 

//this returns null as it internally uses the above line 
await user = _userManager.GetUserAsync(currentClaimPrincipal); 

上面的代碼將調用UserStore.FindByIdAsync起誓用戶ID作爲用戶ID。用戶存儲將因此嘗試通過使用不正確的密鑰來找到應用程序用戶。

黑客應該使用oAuth userId作爲本地用戶表中的PK,但如果兩個oauth提供程序返回相同的id(不太可能),則可能會中斷。當多個oauth標識與相同的應用程序用戶關聯時,它也不會工作。

我的問題

難道我做錯了什麼?用戶ID如何與應用程序用戶存儲和oauth提供程序相關聯?

回答

0

您不應該使用OAuth提供商的聲明主體調用GetUserId。唯一可以使用的ClaimsPrincipal是通過身份使用的ClaimsPrincipalUserFactory生成的。將OAuth與本地用戶相關聯通常通過將OAuth ID鏈接到本地​​用戶ID的AddLogin方法完成。