为啥 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不能在 ServiceStack.Auth 中正确反序列化带有转义的 json 值
Posted
技术标签:
【中文标题】为啥 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不能在 ServiceStack.Auth 中正确反序列化带有转义的 json 值?【英文标题】:Why does UserAuthExtensions.PopulateFromMap(session, jwtPayload) does not deserialize json values with escape correctly in ServiceStack.Auth?为什么 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不能在 ServiceStack.Auth 中正确反序列化带有转义的 json 值? 【发布时间】:2021-12-19 08:02:54 【问题描述】:我们想从 ServiceStack 会话中获取 UserName,但是我们发现 UserName 中的反斜杠没有按预期反序列化。用户名的格式为“域名\用户名”,并在 jwt 令牌中序列化,如下所示:
"typ": "JWT",
"alg": "HS256"
.
"iss": "ssjwt",
"iat": 1635952233,
"exp": 1635955833,
"name": "Robin Doe",
"preferred_username": "domainname\\robindoe"
.[Signature]
调用后:
var sessionFromJwt = JwtAuthProviderReader.CreateSessionFromJwt(req);
userName = sessionFromJwt.UserName;
userName 变量包含值 'domainname\\robindoe'
而不是 'domainname\robindoe'
。
在挖掘 ServiceStack 代码后,我们将其归结为 https://github.com/ServiceStack/ServiceStack/blob/36df74a8b1ba7bf06f85262c1155e1425c082906/src/ServiceStack/Auth/UserAuth.cs#L388 中的 PopulateFromMap() 方法。
为了演示这个问题,我们编写了一个小程序来证明这一点:
class Program
static void Main(string[] args)
var jwtPayload = JsonObject.Parse(@"
""iss"": ""ssjwt"",
""iat"": 1635952233,
""exp"": 1635955833,
""name"": ""John Doe"",
""preferred_username"": ""domainname\\username""
");
var session = new AuthUserSession();
// The PopulateFromMap implementation does not deserialize the json values according to json standards
UserAuthExtensions.PopulateFromMap(session, jwtPayload);
// Notice that the session.UserName still has the escape character 'domainname\\username' instead of the expected 'domainname\username'
Console.WriteLine(session.UserName);
// The PopulateFromMap should deserialize also the values, like in test Can_dynamically_parse_JSON_with_escape_chars()
Can_dynamically_parse_JSON_with_escape_chars();
private const string JsonCentroid = @"""place"": ""woeid"":12345, ""placeTypeName"":""St\\a\/te"" ";
// Source: https://github.com/ServiceStack/ServiceStack.Text/blob/master/tests/ServiceStack.Text.Tests/JsonObjectTests.cs
public static void Can_dynamically_parse_JSON_with_escape_chars()
var placeTypeName = JsonObject.Parse(JsonCentroid).Object("place").Get("placeTypeName");
if (placeTypeName != "St\\a/te")
throw new InvalidCastException(placeTypeName + " != St\\a/te");
placeTypeName = JsonObject.Parse(JsonCentroid).Object("place").Get<string>("placeTypeName");
if (placeTypeName != "St\\a/te")
throw new InvalidCastException(placeTypeName + " != St\\a/te");
为什么 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不能在 ServiceStack.Auth 中正确反序列化带有转义的 json 值?
【问题讨论】:
【参考方案1】:问题是由于枚举 JsonObject
没有返回与索引它相同的转义字符串值,这已从 this commit 解决。
此更改从 v5.12.1+ 开始可用,现在是 available on MyGet。
【讨论】:
感谢您的快速回复!我们现在使用的是 ServiceStack 5.4,并计划更新到最新版本。在我的示例中,您的新解决方案非常完美!同时,我们使用以下代码转义该值:JsonTypeSerializer.Instance.UnescapeString(session.UserName)以上是关于为啥 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不能在 ServiceStack.Auth 中正确反序列化带有转义的 json 值的主要内容,如果未能解决你的问题,请参考以下文章
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?