首页 新闻 会员 周边

如何让 System.Text.Json 兼容 Newtonsoft.Json.Linq.JRaw

0
悬赏园豆:30 [待解决问题]

重现 System.Text.Json 不兼容 JRaw 的代码

var payload = new JwtPayload();
payload.Add("cnf", JRaw.Parse("{\"x5t#S256\":\"foo\"}"));
var newtonsoftJson = Newtonsoft.Json.JsonConvert.SerializeObject(payload);
// output is {"cnf":{"x5t#S256":"foo"}}
var textJson = JsonSerializer.Serialize(payload);
// output is {"cnf":{"x5t#S256":[]}}

IdenitityServer4 受这个问题影响,在 TokenExtensions.cs#L92 中有下面这行代码

var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray();

可能是某个版本的 System.IdentityModel.Tokens.Jwt 开始,json 序列化器改用 System.Text.Json,升级 System.IdentityModel.Tokens.Jwt 后如果使用 cnf 就会遇到这个问题,github 上的相关 issue:

问题补充:

如果不使用 Newtonsoft.Json,全部使用 Sytem.Text.Json,可以用 JsonDocument.Parse 取代 JRaw.Parse

payload.Add("cnf", JsonDocument.Parse("{\"x5t#S256\":\"foo\"}"));
dudu的主页 dudu | 高人七级 | 园豆:31007
提问于:2022-11-19 11:27

System.IdentityModel.Tokens.Jwt 的开源代码 src/System.IdentityModel.Tokens.Jwt

dudu 1年前
< >
分享
所有回答(1)
0

对于 IdenitityServer4 的问题,通过引入 CustomJwtPayload 强制使用 Newtonsoft.Json 对 JwtPayload 进行序列化解决了

TokenExtensions.cs#L36 中将 var payload = new JwtPayload 改为 var payload = new CustomJwtPayload

CustomJwtPayload 的实现如下:

internal class CustomJwtPayload : JwtPayload
{
    public CustomJwtPayload(string issuer, string audience, IEnumerable<Claim> claims, DateTime? notBefore, DateTime? expires) :
        base(issuer, audience, claims, notBefore, expires)
    {
    }

    public override string SerializeToJson()
    {
        return JsonConvert.SerializeObject(this);
    }
}
dudu | 园豆:31007 (高人七级) | 2022-11-19 14:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册