.NET Core 3.1 OpenID Connect ID令牌添加自定义claim不生效问题
问题原因
OnTokenValidated事件的触发时机是IDP返回JWT并完成令牌校验之后,并非你认为的IDP返回令牌前。你在该事件中添加的claim是写入到本地应用用于构建登录态的ClaimsPrincipal对象中,这些声明只会存储到你配置的Cookie登录凭证里,不会修改IDP下发的原始JWT令牌本身。- 你通过
User.Claims读取到的是Cookie反序列化后的本地身份声明,和原始JWT内容无关,因此出现本地可读取、JWT解析工具看不到自定义声明的情况是符合预期的。 - 你开启的
SaveTokens = true配置,保存的也是IDP下发的原始JWT,不会包含后续新增的声明。
解决方法
根据你的实际需求选择对应方案:
- 如果你需要自定义声明存在于IDP签发的原始JWT中:必须在IDP侧配置签发规则,将自定义claim加入到id_token/access_token的签发列表中,客户端侧无法修改IDP下发的原始令牌内容。
- 如果你只需要本地应用使用自定义声明:当前的实现已经满足需求,直接通过
User.Claims读取即可,不需要额外调整。 - 如果你需要在客户端侧生成包含自定义声明的JWT用于内部服务调用:可以基于已经添加完自定义声明的ClaimsPrincipal自行签发新的JWT,参考代码如下:
// 需先安装NuGet包:System.IdentityModel.Tokens.Jwt using System.IdentityModel.Tokens.Jwt; using System.Text; using Microsoft.IdentityModel.Tokens; // 构造签名凭证 var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("替换为你自己的签名密钥")); var signCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); // 生成新JWT var jwtToken = new JwtSecurityToken( issuer: "自定义签发方标识", audience: "自定义接收方标识", claims: claimsIdentity.Claims, expires: DateTime.Now.AddHours(2), signingCredentials: signCredentials); // 序列化得到JWT字符串 string newJwtStr = new JwtSecurityTokenHandler().WriteToken(jwtToken);
注意:自行签发的JWT只能用于你自己控制的服务体系内,无法用于调用原IDP的相关接口。
内容的提问来源于stack exchange,提问作者user1005310
相关产品推荐
相关产品推荐

