首页 > 解决方案 > 为什么 UserAuthExtensions.PopulateFromMap(session, jwtPayload) 不能在 ServiceStack.Auth 中正确反序列化带有转义的 json 值?

问题描述

我们想从 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 值?

标签: jsonservicestackjson-deserializationservicestack-textservicestack-auth

解决方案


问题是由于枚举 a JsonObjectdid not return the same escaped string value as indexing it has been resolved from this commit

此更改从 v5.12.1+ 开始可用,现在可在 MyGet 上使用


推荐阅读