最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Why does an exchanged token in keycloak still show the original token holder profile? - Stack Overflow

programmeradmin3浏览0评论

Worded this question the best I could...

I'm following this guide to enable token exchange between two users in Keycloak.

The idea here is to log in as userA in realmA, and then exchange that access token for userB in realmB. Both users already exist.

Everything seems to work - This gets me an access token for user A in realm A:

KEYCLOAK_HOST="https://..."
SOURCE_REALM_NAME="TEST-source"
SOURCE_CLIENT_NAME="realm_A_login"
SOURCE_CLIENT_SECRET="..."
SOURCE_REALM_USER_NAME="user_A"
SOURCE_REALM_USER_PASSWORD="..."
SOURCE_TOKEN=$(curl -s \
    -X POST \
    "${KEYCLOAK_HOST}/realms/${SOURCE_REALM_NAME}/protocol/openid-connect/token" \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -d "client_id=${SOURCE_CLIENT_NAME}" \
    --data-urlencode "username=${SOURCE_REALM_USER_NAME}" \
    --data-urlencode "password=${SOURCE_REALM_USER_PASSWORD}" \
    -d 'grant_type=password' \
    -d "client_secret=${SOURCE_CLIENT_SECRET}" \
    -d 'scope=openid profile roles' \
    | jq -r .access_token)
echo "SOURCE_TOKEN: ${SOURCE_TOKEN}"

Pulling apart that JWT, we get what I would expect

{
  "exp": 1742287643,
  "iat": 1742244443,
  "aud": "account",
  "sub": "98969f6f-38b7-4bd1-b353-957b88721919",
  "typ": "Bearer",
  ...
  "scope": "openid email profile",
  "email_verified": true,
  "name": "User A",
  "preferred_username": "user_A",
  ...
}

Now, exchange that for a token for user B:

DESTINATION_REALM_NAME="TEST-Destination"
DESTINATION_CLIENT="realm_B_login"
DESTINATION_CLIENT_SECRET="..."
DESTINATION_IDP_NAME="IdP_TEST-source"
USERNAME="........-....-....-....-............"
ACCESS_TOKEN=$(curl -L 
  "${KEYCLOAK_HOST}/realms/${DESTINATION_REALM_NAME}/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 "subject_token=${SOURCE_TOKEN}" \
  --data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
  -d "client_id=${DESTINATION_CLIENT}" \
  -d "client_secret=${DESTINATION_CLIENT_SECRET}" \
  -d "subject_issuer=${DESTINATION_IDP_NAME}" \
  -d "audience=${DESTINATION_CLIENT}" \
  -d "requested_subject=${USERNAME}" \
  -d 'scope=openid profile roles' | jq -r .access_token)
echo "ACCESS_TOKEN: ${ACCESS_TOKEN}"

That seems great - I get an access token back. However, inspecting the token, I seem to have the same user A details:

{
  "exp": 1742287643,
  "iat": 1742244443,
  "jti": "5cf7a005-2c2f-464c-868e-3219c344b543",
  "aud": [
    "account",
    "realm_B_login"
  ],
  "sub": "a91794b9-f566-4162-abf7-544e3127ab70",
  "typ": "Bearer",
  "azp": "realm_B_login",
  "sid": "c7ffe470-0024-42d0-bbad-792ee092d2d3",
  ...
  "scope": "openid email profile",
  "email_verified": false,
  "name": "User A",
  "preferred_username": "[email protected]",
  ...

So - the audience is a little different, and its using email for a username, but its for the user A, not user B.

Pulling up the Keycloak console - lo and behold it created a copy of user A in realm B - and that's what its giving me a token for.

What am I missing here? Reading through the official docs I don't think this is what's supposed to happen... I'm not asking it to create a new user in my destination realm, and I'm clearly saying my requested_subject is user B. Why is it creating a copy of user A, and why isn't it giving me an access token for user B?

发布评论

评论列表(0)

  1. 暂无评论