【发布时间】:2017-02-26 00:46:30
【问题描述】:
我的背景
我正在尝试为 ASP.NET 身份创建自定义用户/角色存储
背景
这里有几个关于在使用 ASP.NET Identity 时获取用户 ID 的问题。他们中的大多数解决了解析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 用户 ID。
由于上述问题而无法运行的代码:
//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,并使用oath 用户ID 作为用户ID。因此,用户存储将尝试使用不正确的密钥来查找应用程序用户。
一个技巧是使用 oAuth userId 作为本地用户表中的 PK,但如果两个 oauth 提供者返回相同的 id(并非不可能),这可能会中断。当多个 oauth 标识与同一个应用程序用户关联时,它也不起作用。
我的问题
我做错了吗?应用程序用户存储和 oauth 提供者之间的用户 ID 是如何关联的?
【问题讨论】:
标签: c# asp.net oauth asp.net-identity asp.net-identity-3