SSO and two different access tokens for two different rest-api backends with different JWT claims requirements

My JS React SPA web application (which is running in the browser) needs to securely access two different rest-api backends which are written in two different programming languages, deployed to two different physical servers and which parse/interpret JWT claims differently.

I want my user to enter username/password only once!

We use OpenId/PKCE - usuall stuff.

Access tokens 1 and 2 should be different in the following way:

  1. ‘Rest Api 1’ is ok to have ‘keycloak user_id’ in the ‘sub’ claim of ‘JWT access token 1’ while ‘Rest Api 2’ expects to have ‘keycloak user_name’ in the ‘sub’ claim of ‘JWT access token 2’.
  2. ‘Rest Api 1’ is ok with any expiration time in the ‘exp’ claim of ‘JWT access token 1’ while ‘Rest Api 2’ expects to have maximum 10 minutes from the current time in the ‘exp’ claim of ‘JWT access token 2’.
  3. ‘aud’ and ‘scp’ claims should have different values, etc.

I cannot change ‘Rest Api 1’ and ‘Rest Api 2’ so they could accept JWTs of the same format.

I assume that I need to create two different Clients for ‘Rest Api 1’ and ‘Rest Api 2’ under the same Realm in Keycloak, am I right? But then how to Sign in into both clients at once and get two different access tokens from them?

Another suitable solution, I suspect, is using ‘token exchange’: Securing Applications and Services Guide

Can somebody advise something?

keycloak-js is used: Securing Applications and Services Guide

If it is not possible to have an SPA signing in in two different clients at the same time and handle the different access tokens, a solution could be using one single client, but configured in a way where it delivers an access token that fits the needs of both Rest Apis. As Api 1 is tolerant and only Api 2 is sensitve I would try to set up access token lifetime to 10 minutes for this client, and set up token mappers which are setting the sub to the keycloak’s username and the aud to [“restapi1”, “restapi2”] (multivalue) or whatever the apis expect as audience. For the audience mapper, keycloak has an integrated mapper type, for the sub claim a javascript mapper may be needed.

“aud” multivalue [“restapi1”, “restapi2”] will work fine.
But can “sub” be also multivalue [user_id_guid, user_name_email] ? I guess it can’t, can it?

Oh, from your description I had understood that it does not matter for Rest Api 1 what is in the sub. If it does matter, my approach won’t work, because sub actually has to be a single value…

1 Like