Unable to retrieve (upstream) Identity Provider's original token

I’m trying to retrieve the upstream Identity Provider’s issued OIDC Token with the KC Token given to my user.
When calling the endpoint described here: https://github.com/keycloak/keycloak-documentation/blob/master/server_development/topics/identity-brokering/tokens.adoc I keep getting a 401 Unauthorized.
I’ve enabled the “Store Token” and “Store Tokens Readable” options on the Identity Provider Configuration page. And I’ve verified that the new user has the broker.read-token role.
I’ve also verified the client has the broker.read-token client role in it’s scope.

Anyone has any idea? If I decode the token on jwt.io, I can’t see the broker.read-token role/claim but I’m not sure it’s represented in the token.

I am having exactly the same issue. Cannot solve it. I’m attempting to do this with Discord (beta) provider. Everything works except brokering. Not sure if this is related to unimplemented features. However judging by what @FireDrunk is saying, this is exactly same thing. Link to original post is here: https://github.com/wadahiro/keycloak-discord/issues/6 (provider itself is working great, i have been using it for few months now)

Problem Restated Below:
I’m having issues retrieving stored tokens based on doc fragment below. I’m getting a message

{
  "errorMessage": "Client [myclient] not authorized to retrieve tokens from identity provider [discord]."
}

Just as a checklist:

Trying brand new user: check
myclient / scope /client role /broker /assigned roles / read-token: check
Identity Providers / discord / store tokens / on
Identiy Providers / discord / stored tokens readable / on

New user after login gets a keycloak token, with this token i access below endpoint
Inspeciting user / role mappings / client roles / broker / assigned roles / read-token: check
/auth/realms/master/broker/discord/token and 403 (above errorMessage)

At this point, i’m thinking maybe because custom provider, have anyone tried to do this. Was your result a success? Any hints? Can we just double check this please?

Below excerpt from the doc:

Retrieving External IDP Tokens
Red Hat Single Sign-On allows you to store tokens and responses from the authentication process with the external IDP. For that, you can use the Store Token configuration option on the IDP’s settings page.

Application code can retrieve these tokens and responses to pull in extra user information, or to securely invoke requests on the external IDP. For example, an application might want to use the Google token to invoke on other Google services and REST APIs. To retrieve a token for a particular identity provider you need to send a request as follows:

GET /auth/realms/{realm}/broker/{provider_alias}/token HTTP/1.1
Host: localhost:8080
Authorization: Bearer {keycloak_access_token}

An application must have authenticated with Red Hat Single Sign-On and have received an access token. This access token will need to have the broker client-level role read-token set. This means that the user must have a role mapping for this role and the client application must have that role within its scope. In this case, given that you are accessing a protected service in Red Hat Single Sign-On, you need to send the access token issued by Red Hat Single Sign-On during the user authentication.

In the broker configuration page you can automatically assign this role to newly imported users by turning on the Stored Tokens Readable switch.```

Could anyone please confirm the steps to do this?

Anyone? Quick confirmation of the “Retrieving External IDP Tokens” Please…

If you can’t see the role in the token, then it’s not getting mapped correctly.
Could be one of two things:

  • not assigned to the user (you’ve confirmed that it is)
  • not mapped correctly for the client that is authenticating

You should be able to see the role in the access token under the resource_access claim like:

"resource_access": {
    "broker": {
      "roles": [
        "read-token"
      ]
    }
}

I think by default, keycloak includes client roles in tokens through the “roles” client scope.
Can you confirm that client scope is applied to the client authenticating?
If you don’t want to use that client scope, you can create the claim through a “User Client Role” mapper as such:

This configuration will inject all client roles a given user has into the token. You can also select a specific client like broker.

Solved, thank you for the hint @trotman23

{
“exp”: 1595126829,
“iat”: 1595126529,
“auth_time”: 1595126527,
“jti”: “74a1eaef-7b3b-4800-fa9a9-sde0b2d6b477d8”,
“iss”: “https://xxxxxxxx”,
“aud”: [
“broker”,
“account”
],
“sub”: “xxxx”,
“typ”: “Bearer”,
“azp”: “concourse-client”,
“nonce”: “5e1d8c42-6831-43ac-8a7b-8413da786d6f”,
“session_state”: “f4ab5158-a6ab-4da9-8e08-697bd2894425”,
“acr”: “1”,
“allowed-origins”: [
http://localhost:42000
],
“realm_access”: {
“roles”: [
“offline_access”,
“uma_authorization”
]
},
“resource_access”: {
“broker”: {
“roles”: [
“read-token”
]
}
},
“scope”: “openid email roles myscope profile”,
“email_verified”: true,
“name”: “abc asdf”,
“groups”: [],
“preferred_username”: “avc”,
“given_name”: “a”,
“family_name”: “b”,
“email”: “avc@gmail.com
}

This is how my token looks like. But when i try to get the IDP token by hitting /auth/realms/{realm}/broker/{provider_alias}/token , It gives me 401.

Frustrating, as there is not proper documentation available. If anyone has solved this, Please help. Thanks in advance.

I was able to do all of the above steps successfully. However when I make the API call:
GET /auth/realms/{realm}/broker/{provider_alias}/token HTTP/1.1
Host: localhost:8080
Authorization: Bearer <KEYCLOAK ACCESS TOKEN>
Specifically I make the API call to Stackoverflow like so:
/auth/realms/{realm}/broker/stackoverflow/token
I get the following response:
access_token=5Gvj6ZAU5GhIs8o7tcAi5w))&expires=86400
I have the following question about what to do next:

  1. What should I do with the access token?
  2. Do I need to decrypt the access token? If so what encryption is being used to encrypt it, base64 or something else?
  3. How do I see the details of the access token?
  4. Do I need to make another Stackoverflow call or Keycloak API call to using this access token as is, to get the details?

Any help would be much appreciated.

Thank you.

I’d like to clarify: is it so that only client which issued the access token may read it?

Cause: I feel this is rather ugly restriction. In my case I use public client to authenticate users using facebook. I do not want to give that client permission to retrieve user tokens. Instead, I’d like to give another client, which is used by the backend process, rights to retrieve user access token and make a request to the upstream IDP for extra information about the user.

Is that doable using standard functionality?

Please help me, how to get Bearer . Because when log in with social KeyCloak not have password of that account. Thanks

I just spent quite a bit of time chasing this down for myself. Hope this helps.

In order for this to work the access token (which is 3 dot-delimited Base64 strings you can decode using any old decoder) must contain:
"resource_access":{"YourActualClient":{"roles":["StandardUser","Users"]},"broker":{"roles":["read-token"]}},

The trick is to get the broker client roles into the token.

  1. Assuming this isn’t in production delete any imported users from keycloak (this is just easier) otherwise you may have extra hassle later.
  2. Make sure both “Store Tokens” and “Store Tokens Readable” are set for your IDP
  3. Go to Client Scopes for your realm (/realms/YourRealm/client-scopes)
  4. Create a new scope called broker_read_token
  5. Make sure “include in token scope” is set.
  6. Create a new Mapper inside “broker_read_token” called “client roles” (auth/admin/master/console/#/create/client-scope/YourRealm/29b7eb82-416b-46e4-aada-5eb982cbc662/mappers)
    a. Change the “Mapper Type” to “User Client Role”
    b. Set the “Client ID” to “broker”
    c. Make sure “Add to Access token” is on
  7. Go back to the top and open settings for your actual client (realms/YourRealm/clients/YourActualClientGUID)
  8. Go to scopes for your actual client and add to default scopes (at least for now) Go back to the top and open settings for your actual client (realms/YourRealm/clients/YourActualClientGUID/client-scopes/setup-scopes)
  9. Test with a new user
1 Like

created a simple project for inspecting idp token

have a look: GitHub - hpl002/keycloak-view-idp-token

2 Likes

I see that the “Stored Tokens Readable” flag does not exist for the built in IDPs (Google, Microsoft, etc.) It only appears for a generic OpenID provider in Keycloak v20.

Is it possible to retrieve the upstream IdP’s original token when the “Stored Tokens Readable” flag isn’t available?

Never mind, I’ve tested it and it works, “Stored Tokens Readable” must be implicit.