使用ASP.NET Core 2.2和Identity Server 4,我具有以下控制器:
[HttpGet("posts"), Authorize]
public async Task<IActionResult> GetPosts() {
var authenticated = this.User.Identity.IsAuthenticated;
var claims = this.User.Identities.FirstOrDefault().Claims;
var id = this.User.FindFirstValue(ClaimTypes.NameIdentifier);
}
我得到了所有claims
,但id
为空...
我检查了claims
中的所有值,并且有一个值为1的“ sub”声明。
为什么ClaimTypes.NameIdentifier没有映射到'sub'?
答案 0 :(得分:1)
要不让Microsoft Identity覆盖声明名称,必须在API启动JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
之前使用app.UseAuthentication()
。
使用直接的“ sub”声明代替ClaimThypes.NameIdentifier,例如
var id = this.User.FindFirstValue("sub");
有关更多参考,请参见有关它的详细讨论: https://github.com/IdentityServer/IdentityServer4/issues/2968#issuecomment-510996164
答案 1 :(得分:0)
我假设在OIDC配置中,您已经使用以下命令清除了Microsoft JWT令牌处理程序上的入站声明类型映射:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
然后,您可以手动设置声明sub
的声明类型映射:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
答案 2 :(得分:0)
静态字符串ClaimTypes.NameIdentifier
具有以下值:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
因此,难怪它不能用于查询sub
声明的值。
如果您知道sub
声明中包含用户ID,则只需使用sub
字符串即可进行查找。
ClaimTypes.NameIdentifier
仅在使用默认入站声明类型映射创建ClaimsPrincipal
的情况下查找用户ID,该默认入站声明类型映射将sub
声明映射到http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
但是即使在这种情况下,使用userManager.Options.ClaimsIdentity.UserIdClaimType
也更合适,因为这是原始映射中使用的实际值(默认为ClaimTypes.NameIdentifier
,但可以自定义)。
(但是,是的,整个映射非常混乱,并且存在许多Github问题,甚至MS开发人员都在哀叹这是纯粹出于遗留原因而存在的邪恶。)