Servicestack GlobalRequestFilters 将额外的用户身份验证数据填充到 Jwt 令牌中

Servicestack GlobalRequestFilters populating additional user auth data into Jwt tokens

我想在用户登录时向响应添加其他属性。

当调用 https://Servicestackservice/auth/credentials?userName=****&password=**** 时,我得到以下响应。我想添加 2 个附加值。日期格式和时区

{ "userId": "21", "sessionId": "****", "userName": "SystemAdmin", "displayName": "System Admin", "referrerUrl":空, "bearerToken": "****", "refreshToken": *", "profileUrl": *", "roles": [ 查看 ], "permissions": [ 查看 ], "responseStatus":{ "errorCode":空, "message":空, "stackTrace":空, "errors":空, "meta": 空 }, "meta": 空 }

I found an example from the SS forums. 我不得不对其进行一些修改以使其成为 运行。

From the SS docs

Modifying the Payload

虽然默认情况下只有有限的信息嵌入到负载中,令牌中嵌入的所有匹配的 AuthUserSession 属性也将填充到 Session 中,您可以将其添加到负载中使用 CreatePayloadFilter 委托。因此,如果您还想访问用户注册的时间,您可以将其添加到负载中:

我希望这就是我如何让他们进入“匹配的 AuthUserSession

          this.GlobalRequestFilters.Add(async (req, res, requestDto) =>
            {
                AuthFilter.AuthResponse(req, res, requestDto);
            });

        public static void AuthResponse(IRequest req, IResponse res, object response)
    {
        var authRes = response as Authenticate;
        if (authRes == null || authRes.UserName == null)
        {
            return;
        }
        var session = (CustomUserSession)req.GetSession();
        if (session != null && session.UserAuthId != null)
        {
            //General Format for US
            string dformat = "g";
            using (var db = HostContext.TryResolve<IDbConnectionFactory>().Open())
            {
                var userAuthExt = db.Single<UserAuthExtension>(ext => ext.UserAuthId == int.Parse(session.UserAuthId));
                if (userAuthExt != null)
                {
                    dformat = userAuthExt.DateTimeFormat;
                }
            }

            authRes.Meta = new Dictionary<string, string> {{"TimeZone", session.TimeZone}, {"DateFormat", dformat}};
        }
    }

添加此内容以尝试获取 JWT 令牌来保存新数据。检查负载,我可以看到 2 个新值已添加到列表中。

   new JwtAuthProvider(AppSettings)
                    {
                        CreatePayloadFilter = (payload, session) =>
                        {

                            if (session != null && session.UserAuthId != null)
                            {
                                //General Format for US
                                string dformat = "g";
                                using (var db = HostContext.TryResolve<IDbConnectionFactory>().Open())
                                {
                                    var userAuthExt = db.Single<UserAuthExtension>(ext => ext.UserAuthId == int.Parse(session.UserAuthId));
                                    if (userAuthExt != null)
                                    {
                                        dformat = userAuthExt.DateTimeFormat;
                                    }
                                }

                                payload["TimeZone"] = ((AuthUserSession) session).TimeZone;
                                payload["DateFormat"] = dformat;
                            }
                        },

您应该 link 您所指的文档,我相信这是您所指的 ServiceStack 的 JWT Modifying the Payload docs. Although it's not clear which example in the Customer Forums

也不清楚问题是什么,我假设是这样的说法:

When calling /auth/credentials?userName=****&password=**** I do not see the new values.

您期望这些值的确切位置是什么?如果您通过凭据进行身份验证,则您不是通过 JWT 进行身份验证,因此您不会在用户会话中填充这些附加属性。如果它们嵌入到您的 JWT 有效载荷中,那么 TimeZone 是一个 AuthUserSession 属性,它 should be populated 如果它包含在 JWT 有效载荷中:

case "TimeZone":
    authSession.TimeZone = entry.Value;
    break;

但是 DateFormat 不是 AuthUserSession 属性,因此您需要通过为 PopulateSessionFilter 提供实现来手动填充它,例如:

new JwtAuthProvider(AppSettings) 
{
    PopulateSessionFilter = (session,payload,req) => 
        session.Meta["DateFormat"] = payload["DateFormat"];
}

但是这些属性只会在通过 JWT 进行身份验证时填充到用户会话中。

为了帮助诊断任何问题,您应该在 CreatePayloadFilter 中设置一个断点以查看您填充 JWT 负载的内容,相反,在您的 PopulateSessionFilter 中设置一个断点以检查其中包含的内容负载和生成的填充会话。