简体   繁体   English

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

[英]Is there an issue with the custom object JSON serialization implementation of System.IdentityModel.Tokens.Jwt for .Net 6?

We migrated from.Net Core (do.net core) 3.1 to.Net 6. We were using the System.IdentityModel.Tokens.Jwt to create a payload and generate a security token with that payload.我们从 .Net Core (do.net core) 3.1 迁移到 .Net 6。我们使用 System.IdentityModel.Tokens.Jwt 来创建有效负载并使用该有效负载生成安全令牌。

Our application has yet to be migrated from Newtonsoft.Json to System.Text.Json due to a lot of nonstandard property serialization that is currently favoring the former.我们的应用程序尚未从Newtonsoft.Json迁移到System.Text.Json ,因为目前有很多非标准属性序列化有利于前者。 The custom claim value contains an object that was previously serialized properly by adhering to the camelCase contract resolver that was specified in the Startup.cs configuration with regards to JSON serialization.自定义声明值包含一个 object,之前已通过遵守在Startup.cs配置中针对 JSON 序列化指定的驼峰式合同解析器正确序列化。

We upgraded from version 5.5.0 of System.IdentityModel.Tokens.Jwt to version 6.16.0 and the serialization is behaving differently.我们从System.IdentityModel.Tokens.Jwt5.5.0版升级到6.16.0版,序列化行为有所不同。

We are using a mixture of IdentityModel well-known claims along with a custom claim.我们混合使用 IdentityModel 知名声明和自定义声明。 The custom claim is the only one that is an object and also the only one behaving this way.自定义声明是唯一一个是 object 的声明,也是唯一一个以这种方式表现的声明。 All other claims are primitive types and are written to the token as specified and expected.所有其他声明都是原始类型,并按照指定和预期写入令牌。

This is an example of the code that is not working:这是不起作用的代码示例:

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

My first hunch was such that it may be related to a conflict with default library of System.Text.Json.我的第一个预感是它可能与 System.Text.Json 的默认库发生冲突有关。 I proceeded to troubleshoot by adding the [JsonPropertyName("name")] attribute to some of the properties but did not succeed.我通过将[JsonPropertyName("name")]属性添加到某些属性来继续进行故障排除,但没有成功。 I expected that if System.Text.Json was being used that at least those description attributes would be respected or consulted during the serialization of the claim object.我预计,如果使用 System.Text.Json,那么在声明 object 的序列化过程中,至少会尊重或参考那些描述属性。

I also tried serializing the value with Newtonsoft JsonConverter.Serialize function and use the serialized value as the value of the claim key-value-pair.我还尝试使用 Newtonsoft JsonConverter.Serialize function 序列化该值,并将序列化值用作声明键值对的值。 However, the stringified object quotes were escaped and found plenty of escaping characters ("****") all over the value which was undesired.然而,字符串化的 object 引号被转义,并发现大量 escaping 字符(“****”)遍及不需要的值。

After some time searching online and trying to come up with the right keywords to search google and GitHub and I finally got to what I, for now, consider a workaround and not a long-term solution.在网上搜索了一段时间并尝试提出正确的关键字来搜索 google 和 GitHub 之后,我终于找到了我现在考虑的解决方法而不是长期解决方案。

The clue was provided by this open issue on Github. I simply, to my interpretation, forced the use of the Newtonsoft serializing and deserializing delegates by specifying the following lines before instantiation of payload variable posted in the question:线索由 Github 上的这个公开问题提供。根据我的解释,我只是在问题中发布的有效负载变量实例化之前指定以下行,从而强制使用 Newtonsoft 序列化和反序列化委托:

JsonExtensions.Serializer = JsonConvert.SerializeObject;
JsonExtensions.Deserializer = JsonConvert.DeserializeObject;

This was the first indication of potentially System.Text.Json being forced from deep within a library.这是潜在的 System.Text.Json 被从库深处强制获取的第一个迹象。 It may also be an indication that the time has come to prioritize the migration to System.Text.Json from Newtonsoft.Json .这也可能表明是时候优先从Newtonsoft.Json迁移到System.Text.Json了。

I hope this workaround helps somebody else get to this short-term patch, and not spend as much as I did.我希望这个解决方法可以帮助其他人获得这个短期补丁,而不是像我那样花费太多。

If I find anymore concrete ideas or clues about this matter, I will update this answer.如果我发现有关此事的更多具体想法或线索,我将更新此答案。

The code below works下面的代码有效

    /* 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);

I am thankful for the issue on github, but more importantly to the solution suggested here .感谢 github 上的问题,但更重要的是感谢这里建议的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用ASP.NET 5中的System.IdentityModel.Tokens.Jwt编码JWT令牌 - Encoding JWT Token Using System.IdentityModel.Tokens.Jwt in ASP.NET 5 如何为 JwtBearer 和 System.IdentityModel.Tokens.Jwt 在 asp.net 内核中自定义承载 header 关键字? - How to customize bearer header keyword in asp.net core for JwtBearer and System.IdentityModel.Tokens.Jwt? 使用System.IdentityModel.Tokens.Jwt从5.1迁移到2.0后,JWTAuthentication无法在asp.net core 2.0中运行 - 5.1.4更新 - JWTAuthentication not working in asp.net core 2.0 after migrate from 1.1 to 2.0 with System.IdentityModel.Tokens.Jwt - 5.1.4 update .NET Core 3 System.Text.Json 嵌套 object 序列化 - .NET Core 3 System.Text.Json nested object serialization System.IdentityModel.Tokens 和 Microsoft.IdentityModel.Tokens 有什么区别? 我应该在 ASP.NET Core 应用程序中使用哪一个? - What is the different between System.IdentityModel.Tokens & Microsoft.IdentityModel.Tokens? Which one should I use in an ASP.NET Core application? MSOnline 无法加载类型“System.IdentityModel.Tokens.JwtSecurityToken” - MSOnline Could not load type 'System.IdentityModel.Tokens.JwtSecurityToken' .NET核心对象JSON序列化为Javascript格式 - .NET Core Object JSON Serialization to Javascript format 如何从 JWT 令牌中获取不记名令牌(system.identitymodel.token.jwt.jwtsecuritytoken) - how to get bearer token out of JWT token (system.identitymodel.token.jwt.jwtsecuritytoken) ASP.NET Core 和 JSON Web 令牌 - 自定义声明映射 - ASP.NET Core and JSON Web Tokens - Custom claims mapping 针对匿名对象的 System.Text.Json 序列化 - System.Text.Json serialization against an anonymous object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM