.Net 6 的 System.IdentityModel.Tokens.Jwt 的自定义对象 JSON 序列化实现是否存在问题?

Ivá*_*lpo 5 jwt asp.net-core asp.net-core-webapi identitymodel .net-6.0

我们从 .Net Core (dotnet core) 3.1 迁移到 .Net 6。我们使用 System.IdentityModel.Tokens.Jwt 创建有效负载并使用该有效负载生成安全令牌。

我们的应用程序尚未从Newtonsoft.Json迁移到System.Text.Json,因为许多非标准属性序列化目前更倾向于前者。自定义声明值包含一个之前通过遵守Startup.cs配置中指定的有关 JSON 序列化的驼峰命名约定解析器正确序列化的对象。

我们从System.IdentityModel.Tokens.Jwt版本5.5.0升级到版本6.16.0,序列化的行为有所不同。

我们混合使用了 IdentityModel 众所周知的声明和自定义声明。自定义声明是唯一一个作为对象的声明,也是唯一一个具有这种行为方式的声明。所有其他声明都是原始类型,并按照指定和预期写入令牌。

这是不起作用的代码示例:

 var payload = new JwtPayload()
            {
                {JwtRegisteredClaimNames.Iss, issuer},
                {JwtRegisteredClaimNames.Iat, now},
                {JwtRegisteredClaimNames.Nbf, now},
                {JwtRegisteredClaimNames.Exp, exp},
                {JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N")},
                {"role", user.UserType},
                {"customClaim", customClaimObjectInstance }
            };

var jwt = new JwtSecurityToken(_jwtHeader, payload);

/* Token below contains a valid base64 encoded JWT Token with
   the customClaim property containing pascal values that match
   the properties of the C# Poco object and not at all following       
   either default convention or even any JsonProperty description 
   attributes such as [JsonProperty("name")] that may decorate each 
   property of the custom object */
var token = _jwtSecurityTokenHandler.WriteToken(jwt);
Run Code Online (Sandbox Code Playgroud)

我的第一预感是这可能与 System.Text.Json 默认库的冲突有关。我通过将属性添加到某些属性来继续进行故障排除[JsonPropertyName("name")],但没有成功。我预计,如果使用 System.Text.Json,那么在声明对象的序列化过程中至少会尊重或参考这些描述属性。

我还尝试使用 Newtonsoft JsonConverter.Serialize函数序列化该值,并使用序列化值作为声明键值对的值。但是,字符串化对象引号被转义,并在值中发现了大量转义字符(“****”),这是不需要的。

Ivá*_*lpo 4

经过一段时间的在线搜索并尝试找到正确的关键字来搜索 google 和 GitHub,我终于找到了目前我认为的解决方法,而不是长期解决方案。

Github 上的这个开放问题提供了线索。根据我的解释,我只是通过在问题中发布的有效负载变量实例化之前指定以下行来强制使用 Newtonsoft 序列化和反序列化委托:

JsonExtensions.Serializer = JsonConvert.SerializeObject;
JsonExtensions.Deserializer = JsonConvert.DeserializeObject;
Run Code Online (Sandbox Code Playgroud)

这是潜在的 System.Text.Json 被强制从库深处的第一个迹象。这也可能表明,是时候优先考虑从System.Text.Json到 的迁移了Newtonsoft.Json

我希望这个解决方法可以帮助其他人获得这个短期补丁,而不是像我那样花那么多钱。

如果我发现有关此事的更多具体想法或线索,我会更新此答案。

下面的代码有效

    /* This was the key to achieving the prior result, however 
       temporary it may be. */
        JsonExtensions.Serializer = JsonConvert.SerializeObject;
        JsonExtensions.Deserializer = JsonConvert.DeserializeObject;
        
        var payload = new JwtPayload()
        {
            {JwtRegisteredClaimNames.Iss, issuer},
            {JwtRegisteredClaimNames.Iat, now},
            {JwtRegisteredClaimNames.Nbf, now},
            {JwtRegisteredClaimNames.Exp, exp},
            {JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N")},
            {"role", user.UserType},
            { "customClaim", customClaimObjectInstance}
       };

       var jwt = new JwtSecurityToken(_jwtHeader, payload);
       var token = _jwtSecurityTokenHandler.WriteToken(jwt);
Run Code Online (Sandbox Code Playgroud)

我感谢 github 上的问题,但更重要的是这里建议的解决方案。