Asp.net core 为什么ClaimTypes.NameIdentifier没有映射到';子&x27;?

Asp.net core 为什么ClaimTypes.NameIdentifier没有映射到';子&x27;?,asp.net-core,identityserver4,asp.net-core-2.2,Asp.net Core,Identityserver4,Asp.net Core 2.2,使用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;

使用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);

}
[HttpGet(“posts”),授权]
公共异步任务GetPosts(){
var authenticated=this.User.Identity.IsAuthenticated;
var claims=this.User.identies.FirstOrDefault().claims;
var id=this.User.FindFirstValue(ClaimTypes.NameIdentifier);
}
我得到了所有的
声明
,但是
id
为空

我检查了
索赔中的所有值,我有一个值为1的“sub”索赔


为什么ClaimTypes.NameIdentifier没有映射到“sub”?

我假设在OIDC配置中,您已通过以下方式清除Microsoft JWT令牌处理程序上的入站索赔类型映射:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
然后,您可以手动设置索赔
sub
的索赔类型映射:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);

静态字符串
ClaimTypes.NameIdentifier
具有以下值:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

因此,难怪它不能用于查找
sub
索赔的值

如果您知道
sub
声明包含用户id,那么只需使用
sub
字符串即可进行查找

ClaimTypes.NameIdentifier
仅在使用默认入站索赔类型映射创建
ClaimsPrincipal
的情况下用于查找用户id,该映射将
索赔映射到
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

但即使在这种情况下,也更适合使用
userManager.Options.ClaimsIdentity.UserIdClaimType
,因为这是原始映射中使用的实际值(默认为
ClaimTypes.nameignifier
,但可以自定义)

(但是,是的,这整个映射非常混乱,并且有许多Github问题已经公开,甚至连开发人员都哀叹这是一个仅仅因为遗留原因而存在的邪恶。)

  • 要不让Microsoft Identity覆盖声明名称,必须使用
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear()就在API启动中的
    app.UseAuthentication()
    之前

  • 使用直接“sub”声明代替ClaimThypes.NameIdentifier,例如。
    var id=this.User.FindFirstValue(“sub”)

  • 如需进一步参考,请参阅详细讨论:

    尝试设置:JwtSecurityTokenHandler.DefaultMapInboundClaims=false;这主要是为了修复以下事实:
    sub
    声明被转换为
    nameidentifier
    声明。它没有解决这个问题。。。id仍然为空。这是一个很好的问题,这就是为什么我对它进行了升级(从-1到0),但您的示例与您的问题无关。如果您在声明中看到“sub”,则查找“sub”的fIRSTVALUE。我尝试了您的建议,但仍然为空。。。不知道发生了什么…如果删除这行怎么办:
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear()调用Clear时,我在System.Private.CoreLib.dll中得到错误“System.ArgumentException:”已添加具有相同密钥的项。Key:sub'
    尝试删除此行:
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear()
    ,还有这个
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add(“sub”,ClaimTypes.NameIdentifier)
    ,删除两个CodesHank很多…当DefaultInboundClaimTypeMap.Clear()遇到其他问题时,您的代码添加NameIdentifier声明类型