Reputation: 2027
I want to add additional properties to the response when a user logs in.
When calling https://Servicestackservice/auth/credentials?userName=****&password=**** I get the below response. I want to add 2 additional values. DateFormat & TimeZone
{ "userId": "21", "sessionId": "****", "userName": "SystemAdmin", "displayName": "System Admin", "referrerUrl": null, "bearerToken": "****", "refreshToken": *", "profileUrl": *", "roles": [ View ], "permissions": [ View ], "responseStatus": { "errorCode": null, "message": null, "stackTrace": null, "errors": null, "meta": null }, "meta": null }
I found an example from the SS forums. I had to modify it some to make it run.
Modifying the Payload
Whilst only limited info is embedded in the payload by default, all matching AuthUserSession properties embedded in the token will also be populated on the Session, which you can add to the payload using the CreatePayloadFilter delegate. So if you also want to have access to when the user was registered you can add it to the payload with:
I am hoping this is how i get them into the "matching 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}};
}
}
Adding this to try to get the JWT tokens to hold the new data. Examining the payload i can see the 2 new values are added to the list.
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;
}
},
Upvotes: 1
Views: 100
Reputation: 143319
You should link to the docs you're referring to, which I believe is ServiceStack's JWT Modifying the Payload docs. Although it's not clear which example in the Customer Forums you're referring to.
It's also not clear what the question is, I'm assuming it's this statement:
When calling /auth/credentials?userName=****&password=**** I do not see the new values.
Where exactly are you expecting these values? If you're authenticating by credentials you're not Authenticating by JWT so you will not have these additional properties populated on your User Session. If they're embedded in your JWT's body payload then as TimeZone
is a AuthUserSession property, it should be populated if it was contained within the JWT payload:
case "TimeZone":
authSession.TimeZone = entry.Value;
break;
But DateFormat
is not an AuthUserSession
property so you will need to populate it manually by providing an implementation for PopulateSessionFilter
, e.g:
new JwtAuthProvider(AppSettings)
{
PopulateSessionFilter = (session,payload,req) =>
session.Meta["DateFormat"] = payload["DateFormat"];
}
But these properties are only going populated in the Users Session when authenticating via JWT.
To help diagnose any issues you should but a breakpoint in your CreatePayloadFilter
to see what you've populated the JWT payload with and conversely put a breakpoint in your PopulateSessionFilter
to inspect what's contained in the payload and resulting populated session.
Upvotes: 1