invalid_token error when exchanging google id_token for a set of keycloak tokens

Viewed 1437

I'm creating an auth flow between a mobile application and keycloak using google as identity provider.I have run into problems when trying to exchange google id-token for a keycloak set of JWT tokens.

For the client (app side) I've set up the native GoogleSignin (called with "userinfo.profile" and "userinfo.email" scopes] and created an OAuth2 android client in the Google Developer Console.

I've also created a web client in the Google console to obtain the client_id and client_secret credentials (for use with keycloak), and added the redirect_url

In the keycloak dashboard I've set up google as identity provider using the web-client credentials, with a token-exchange policy for my-app client within my-realm.

At this point after signing-in in the app I get a JWT id_token from Google:

{:scopes #js ["https://www.googleapis.com/auth/userinfo.profile" "https://www.googleapis.com/auth/userinfo.email"], :serverAuthCode nil, :idToken "eyJhb...", :user #js {:photo "http://photo.jpg", :email "fubar@fu.bar", :familyName "Bar", :givenName "Fu", :name "Fu Bar", :id "1234"}}

I than ask keycloak to exchange it for its own tokens within the realm, so that the app can go back to a "normal" auth flow:

curl -X POST \
    -d "client_id=my-app" \
    -d "client_secret=mkU..." \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
    --data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
    -d "subject_issuer=google" \
    -d "audience=my-app" \
    -d "subject_token=${idToken}" \
    http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/token

but it fails, with keycloak logging a "call failure" :

keycloak_1  | 12:17:39,810 DEBUG [org.keycloak.authentication.AuthenticationProcessor] (default task-1) AUTHENTICATE CLIENT
keycloak_1  | 12:17:39,810 DEBUG [org.keycloak.authentication.ClientAuthenticationFlow] (default task-1) client authenticator: client-secret
keycloak_1  | 12:17:39,811 DEBUG [org.keycloak.authentication.ClientAuthenticationFlow] (default task-1) client authenticator SUCCESS: client-secret
keycloak_1  | 12:17:39,811 DEBUG [org.keycloak.authentication.ClientAuthenticationFlow] (default task-1) Client authenticated by client-secret
keycloak_1  | 12:17:39,839 DEBUG [org.keycloak.broker.oidc.OIDCIdentityProvider] (default task-1) GOOGLE userInfoUrl: https://openidconnect.googleapis.com/v1/userinfo
keycloak_1  | 12:17:39,892 DEBUG [org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider] (default task-1) Failed to invoke user info status: 401

keycloak_1  | 10:49:10,055 WARN  [org.keycloak.events] (default task-9) type=TOKEN_EXCHANGE_ERROR, realmId=my-realm, clientId=my-app, userId=null, ipAddress=172.18.0.1, error=invalid_token, reason='user info call failure', auth_method=token_exchange, grant_type=urn:ietf:params:oauth:grant-type:token-exchange, subject_issuer=google, validation_method='user info', client_auth_method=client-secret
1 Answers

To answer my own question: the solution is to obtain access_token (not identity_token) from google, which can than be exchanged without problems.

Related