我们从 .Net Core (dotnet core) 3.1 迁移到 .Net 6。我们使用 System.IdentityModel.Tokens.Jwt 创建有效负载并使用该有效负载生成安全令牌。
我们的应用程序尚未从Newtonsoft.Json迁移到System.Text.Json,因为目前有很多非标准的属性序列化有利于前者。自定义声明值包含一个对象,该对象先前通过遵守在Startup.cs配置中指定的关于 JSON 序列化的 camelCase 合同解析器而正确序列化。
我们从 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);
我的第一个预感是它可能与 System.Text.Json 的默认库冲突有关。我通过将[JsonPropertyName("name")]
属性添加到某些属性来进行故障排除,但没有成功。我希望如果使用 System.Text.Json,那么在声明对象的序列化过程中至少会尊重或参考这些描述属性。
我还尝试使用 Newtonsoft JsonConverter.Serialize函数对值进行序列化,并将序列化值用作声明键值对的值。但是,字符串化的对象引号被转义,并在整个值上发现了大量的转义字符(“****”),这是不希望的。
经过一段时间的在线搜索并尝试找到正确的关键字来搜索 google 和 GitHub,我终于得到了我现在考虑的解决方法,而不是长期解决方案。
线索是由Github 上的这个公开问题提供的。根据我的解释,我只是通过在问题中发布的有效负载变量的实例化之前指定以下几行来强制使用 Newtonsoft 序列化和反序列化委托:
JsonExtensions.Serializer = JsonConvert.SerializeObject;
JsonExtensions.Deserializer = JsonConvert.DeserializeObject;
这是 System.Text.Json 可能被从库深处强制执行的第一个迹象。这也可能表明是时候优先考虑迁移到System.Text.Json
from 了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);
我很感谢 github 上的问题,但更重要的是这里建议的解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句