首页 新闻 会员 周边 捐助

.NET:JwtSecurityTokenHandler 不支持类型为 JsonClaimValueTypes.Json 的 Claim

0
悬赏园豆:30 [已解决问题] 解决于 2025-05-02 17:29

在将 IdentityServer4 从 .net 7 升级至 .net 9 时遇到的问题,升级过程中将 System.IdentityModel.Tokens.Jwt 从 6.25.0 升级至 8.9.0,升级后下面的测试失败,完整代码见 JwtRequestAuthorizeTests.cs#L490

var someObj = new { foo = new { bar = "bar" }, baz = "baz" };
var someObjJson = JsonSerializer.Serialize(someObj);
var someArr = new[] { "a", "b", "c" };
var someArrJson = JsonSerializer.Serialize(someArr);

var requestJwt = CreateRequestJwt(
    issuer: _client.ClientId,
    audience: IdentityServerPipeline.BaseUrl,
    credential: new X509SigningCredentials(TestCert.Load()),
    claims: new[] {
        //...,
        new Claim("someObj", someObjJson, Microsoft.IdentityModel.JsonWebTokens.JsonClaimValueTypes.Json),
        new Claim("someArr", someArrJson, Microsoft.IdentityModel.JsonWebTokens.JsonClaimValueTypes.JsonArray),
});

var url = _mockPipeline.CreateAuthorizeUrl(
    clientId: _client.ClientId,
    responseType: "id_token",
    extra: Parameters.FromObject(new
    {
        request = requestJwt
    }));
var response = await _mockPipeline.BrowserClient.GetAsync(url);

_mockPipeline.LoginRequest.Should().NotBeNull();

_mockPipeline.LoginRequest.Parameters["someObj"].Should().NotBeNull();

_mockPipeline.LoginRequest.Parameters 中不存在 key 为 someObj 的参数

问题补充:

CreateRequestJwt 对于的实现代码:

string CreateRequestJwt(string issuer, string audience, SigningCredentials credential, Claim[] claims, bool setJwtTyp = false)
{
    var handler = new JwtSecurityTokenHandler();
    handler.OutboundClaimTypeMap.Clear();

    var token = handler.CreateJwtSecurityToken(
        issuer: issuer,
        audience: audience,
        signingCredentials: credential,
        subject: Identity.Create("pwd", claims));

    if (setJwtTyp)
    {
        token.Header["typ"] = JwtClaimTypes.JwtTypes.AuthorizationRequest;
    }

    return handler.WriteToken(token);
}

claims 值转给了 ClaimsIdentity

subject: Identity.Create("pwd", claims));
dudu的主页 dudu | 高人七级 | 园豆:24728
提问于:2025-05-02 17:02
< >
分享
最佳答案
0

这是 System.IdentityModel.Tokens.Jwt 7.0 开始引入的一个 breaking change,在 JWT 序列化时会忽略 json 类型的
System.Security.Claims.Claim

github 上的相关 issue:

dudu | 高人七级 |园豆:24728 | 2025-05-02 17:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册