/access-token issue/question - how to override the "sub" claim

I have an app with a custom auth provider, using Basic, Credentials, and JWT auth. The /auth/credentials api returns a bearer token and refresh token and the payloads are fine. We authenticate just fine with the bearer token too, and the refresh token has the right “sub” claim in it as well (which for us is a GUID). However, when we call the /access-token service to get a new bearer token (this is from a disconnected client) with a valid refresh token, we get an access token back, BUT, the access token has { “sub”: “0” }, while the rest of the payload claims are correct. I need to be able to override this somewhere in the GetAccessTokenService to use the Guid ID of our user.

I think the PopulateSession(…) might be assuming the UserAuthId is an integer instead of what this app uses which is a Guid.

If there is no override for us, what would be the best way for us to remove the /access-token service and replace it with our own implementation? Thanks for your help.

The JWT sub is populated with AuthUserSession.UserAuthId which is a string so you should just be able to populate that with your Guid string.

I guess, i’m just not sure where to do that for the /access-token service. Because the PopulateSession method is overriding the UserAuthId field looks like, so seems like i’d have to set that field after the PopulateSession method runs.

I can put in a temporary fix to this using the CreatePayloadFilter, but I have to re-query the user from the UserAuthRepository which doesn’t seem ideal. This is the temporary fix:

CreatePayloadFilter = (jsonObject, authSession) =>
{
	if (!authSession.UserAuthId.IsGuid())
	{
		var userRepo = ServiceStackHost.Instance.TryResolve<IUserAuthRepository>();
		var userAuth = userRepo.GetUserAuthByUserName(authSession.UserName) as CustomUserAuth;
		if (userAuth != null)
		{
			jsonObject["sub"] = userAuth.Key.ToString();

			// save the session if possible
			var currentRequest = ServiceStackHost.Instance.TryGetCurrentRequest();
			if (currentRequest != null)
			{
				authSession.UserAuthId = userAuth.Key.ToString();
				currentRequest.SaveSession(authSession);
			}
		}
	}
}

It should just be in your Custom AuthProvider when it creates the UserSession.

The /access-token creates a JWT from a Refresh Token. Since you’re not using a built-in Auth Repository you’ll need to implement IUserSessionSource either on your Custom AuthProvider or as a registered dependency in the IOC.

I converted the code to use IUserSessionSource as a dependency in the IOC. Thanks!

1 Like