We use Keycloak 12.02 for this test.
The idea is that we have a lot of customers, that we all have in their own realms. We want to be able to impersonate a user in any non-master realm for an admin/support user in the master realm.
The flow would be to:
- login using a super-user/password to login into the
master
realm - get a list of all available realms and their users
- craft a request to exchange the current access token with a new access token for that specific user.
It is the last step I cannot get to work.
Example:
Login to master realm
token=$(curl -s -d 'client_id=security-admin-console'
-d 'username=my-super-user' -d 'password=my-super-pass' \
-d 'grant_type=password' \
'https://login.example.net/auth/realms/master/protocol/openid-connect/token' | jq -r .access_token)
(we now have an access token for the super-user in the master realm)
The Keycloak server has enabled token exchange (-Dkeycloak.profile.feature.token_exchange=enabled) as described here https://www.keycloak.org/docs/latest/securing_apps/#_token-exchange.
Attempt to impersonate a user in another realm (not master):
curl -s -X POST "https://login.example.net/auth/realms/some_realm/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d 'client_id=some_client' \
-d "requested_subject=some_user" \
-d "subject_token=$token"
However, this does not work. The result is: {"error":"invalid_token","error_description":"Invalid token"}
(Doing this inside a single realm work)
What am I doing wrong here? This seems like a very normal feature to utilize in a real-life deployment, so any help is much appreciated!
UPDATE: First of all, I found the very same use-case here: https://lists.jboss.org/pipermail/keycloak-user/2019-March/017483.html
Further, I can get it to work by working through some major hoops. As described above, one can use the broker
client in the master
realm as an identity provider:
- Login as super-user
adminA
->TokenA
- use
TokenA
to get a new external token,TokenExt
from themaster
identity provider. - Use
TokenExt
to do a token exchange for the user you want to impersonate
The caveat with the above is that the user adminA
is created in each of the realms you log into with this method, so still not ideal.
master
as an identity provider, groups of organization admins, fine-grained authority given for token exchange, etc in each realm we create. The main downside is like you said the implicitly created user in the "child" realms. How can you configure it to be created "each time from scratch"? – Fumigator