Hello,
I’m testing the TokenExchange flow implementation with Keycloak. I’m using the documentation Using token exchange - Keycloak
This is my environment:
-
1 “custom-auth” client used to request token exchange
-
1 identity provider “github” with “Permissions enabled” set to “On”.
- Configuring the token-exchange permission:
- Configuring the associated policy: positive + 2 clients: “custom-auth” and “realm-management”
I. When I succeed to use the internal to external function
- the user doesn’t exist
- I connect to
http://localhost:8080/realms/dev/account
with the provider (github) - I retrieve the token with F12
- execute the token-exchange request:
POST - http://localhost:8080/realms/dev/protocol/openid-connect/token
BODY (x-www-form-urlencoded)
client_id = custom-auth
grant_type = urn:ietf:params:oauth:grant-type:token-exchange
subject_token = [F12 token]
requested_token_type = urn:ietf:params:oauth:token-type:access_token
requested_issuer = github
- I get a valid response:
{
"access_token": "gho_[...]",
"expires_in": 0,
"refresh_expires_in": 0,
"not-before-policy": 0,
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"account-link-url": "http://localhost:8080/realms/dev/broker/github/link?nonce=[...]&hash=[...]&client_id=custom-auth"
}
II. Case that doesn’t work (1)
- With the same user (from I.), I add a password via the “Credentials” tab
- I retrieve a token:
curl -d client_id=custom-auth -d username=killian -d password=azerty -d grant_type=password http://localhost:8080/realms/dev/protocol/openid-connect/token
- execute the token-exchange request
POST - http://localhost:8080/realms/dev/protocol/openid-connect/token
BODY (x-www-form-urlencoded)
client_id = custom-auth
grant_type = urn:ietf:params:oauth:grant-type:token-exchange
subject_token = [curl's token]
requested_token_type = urn:ietf:params:oauth:token-type:access_token
requested_issuer = github
- I get an error (not normal in my opinion):
{
"error_description": "identity provider is not linked, can only link to current user session",
"account-link-url": "http://localhost:8080/realms/dev/broker/github/link?nonce=...&hash=...&client_id=custom-auth",
"error": "not_linked"
}
The doc says “The user must have logged in with the external identity provider at least once”. However,
I have the feeling that the only tokens that work are those generated from a connection via the provider.
If this is the case, how can I get this access token with curl?
III. Case that doesn’t work (2)
- I create a user with a password, but it’s not linked to a github account
- I get a token:
curl -d client_id=custom-auth -d username=killian -d password=azerty -d grant_type=password http://localhost:8080/realms/dev/protocol/openid-connect/token
- execute the token-exchange request:
POST - http://localhost:8080/realms/dev/protocol/openid-connect/token
BODY (x-www-form-urlencoded)
client_id = custom-auth
grant_type = urn:ietf:params:oauth:grant-type:token-exchange
subject_token = [curl's token]
requested_token_type = urn:ietf:params:oauth:token-type:access_token
requested_issuer = github
- I get an error (normal):
{
"error_description": "identity provider is not linked, can only link to current user session",
"account-link-url": "http://localhost:8080/realms/dev/broker/github/link?nonce=...&hash=...&client_id=custom-auth",
"error": "not_linked"
}
- I then execute the following query (adding redirect_uri as indicated in the doc):
GET - http://localhost:8080/realms/dev/broker/github/link?nonce=...&hash=...&client_id=custom-auth&redirect_uri=http://localhost:8080/realms/dev/account
- I am redirected without error (code 200), but the account is not linked, I was never redirected to github
IV. Questions
Am I doing something wrong?
I have the feeling that the “Client initiated account linking” API isn’t working properly => Server Developer Guide
To sum up, does the “account-link-url” work as I understand it and why is it only the tokens from http://localhost:8080/realms/dev/account/
(client acount-console) that work?
Thanks in advance for your answers!