为什么 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不反序列化 json 值并在 ServiceStack.Auth 中正确转义?
Why does UserAuthExtensions.PopulateFromMap(session, jwtPayload) does not deserialize json values with escape correctly in ServiceStack.Auth?
我们想从 ServiceStack 会话中获取 UserName,但我们发现 UserName 中的反斜杠没有按预期进行反序列化。 UserName 具有这种格式 'domainname\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 值?
问题是由于枚举 JsonObject
没有 return 与索引相同的转义字符串值,已从 this commit.
中解决
此更改适用于 v5.12.1+,即现在 available on MyGet。
我们想从 ServiceStack 会话中获取 UserName,但我们发现 UserName 中的反斜杠没有按预期进行反序列化。 UserName 具有这种格式 'domainname\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 值?
问题是由于枚举 JsonObject
没有 return 与索引相同的转义字符串值,已从 this commit.
此更改适用于 v5.12.1+,即现在 available on MyGet。