From 22013667d13212c965f9fd552ebd23cf02c73842 Mon Sep 17 00:00:00 2001 From: Mauro Mugnaini Date: Mon, 6 May 2024 18:10:26 +0200 Subject: [PATCH] Token exchage for an offline token now raises an IllegalArgumetException if the original token not contains `offline_access` within its scopes, required by the `v24.0.2` version of the Keycloak --- .../keycloak/DefaultKeycloakClient.java | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/gcube/common/keycloak/DefaultKeycloakClient.java b/src/main/java/org/gcube/common/keycloak/DefaultKeycloakClient.java index ef23aa1..8544099 100644 --- a/src/main/java/org/gcube/common/keycloak/DefaultKeycloakClient.java +++ b/src/main/java/org/gcube/common/keycloak/DefaultKeycloakClient.java @@ -42,6 +42,7 @@ import org.gcube.common.gxhttp.util.ContentUtils; import org.gcube.common.gxrest.request.GXHTTPStringRequest; import org.gcube.common.gxrest.response.inbound.GXInboundResponse; import org.gcube.common.gxrest.response.inbound.JsonUtils; +import org.gcube.common.keycloak.model.AccessToken; import org.gcube.common.keycloak.model.JSONWebKeySet; import org.gcube.common.keycloak.model.ModelUtils; import org.gcube.common.keycloak.model.PublishedRealmRepresentation; @@ -720,22 +721,31 @@ public class DefaultKeycloakClient implements KeycloakClient { null); } -// @Override -// public TokenResponse exchangeTokenForOfflineToken(String context, String oidcAccessToken, String clientId, -// String clientSecret, String audience) throws KeycloakClientException { -// -// return exchangeTokenForOfflineToken(getTokenEndpointURL(getRealmBaseURL(context)), oidcAccessToken, clientId, -// clientSecret, audience); -// } + @Override + public TokenResponse exchangeTokenForOfflineToken(String context, String oidcAccessToken, String clientId, + String clientSecret, String audience) throws IllegalArgumentException, KeycloakClientException { -// @Override -// public TokenResponse exchangeTokenForOfflineToken(URL tokenURL, String oidcAccessToken, String clientId, -// String clientSecret, String audience) throws IllegalArgumentException, KeycloakClientException { -// -// // ModelUtils.getAccessTokenFrom(oidcTokenResponse).getScope(). -// return exchangeToken(tokenURL, oidcAccessToken, clientId, clientSecret, audience, REFRESH_TOKEN_TOKEN_TYPE, -// OFFLINE_ACCESS_SCOPE); -// } + return exchangeTokenForOfflineToken(getTokenEndpointURL(getRealmBaseURL(context)), oidcAccessToken, clientId, + clientSecret, audience); + } + + @Override + public TokenResponse exchangeTokenForOfflineToken(URL tokenURL, String oidcAccessToken, String clientId, + String clientSecret, String audience) throws IllegalArgumentException, KeycloakClientException { + + AccessToken at = null; + try { + at = ModelUtils.getAccessTokenFrom(oidcAccessToken); + } catch (Exception e) { + throw new IllegalArgumentException("Impossible to parse the access token as JSON", e); + } + if (at.getScope().indexOf(OFFLINE_ACCESS_SCOPE) < 0) { + logger.info("Token to be exchanged doesn't contain 'offline_token' within scopes"); + throw new IllegalArgumentException("Orignal access token doesn't contain the 'offline_token' scope"); + } + return exchangeToken(tokenURL, oidcAccessToken, clientId, clientSecret, audience, REFRESH_TOKEN_TOKEN_TYPE, + OFFLINE_ACCESS_SCOPE); + } /** * Queries from the OIDC server an exchanged token by using provided access token, for the given audience (context),