diff --git a/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java b/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java
index 9b845dd..e25b2aa 100644
--- a/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java
+++ b/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java
@@ -71,6 +71,23 @@ public class OpenIdConnectRESTHelper {
public static JWTToken queryClientToken(String clientId, String clientSecret, URL tokenURL)
throws OpenIdConnectRESTHelperException {
+ return queryClientToken(clientId, clientSecret, tokenURL, null);
+ }
+
+ /**
+ * Queries from the OIDC server an OIDC access token, by using provided clientId and client secret.
+ *
+ * @param clientId the client id
+ * @param clientSecret the client secret
+ * @param tokenUrl the token endpoint {@link URL} of the OIDC server
+ * @param extraHeaders extra HTTP headers to add to the request (e.g. X-D4Science-Context
custom header), may be null
+ * @return the issued token
+ * @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
+ */
+ public static JWTToken queryClientToken(String clientId, String clientSecret, URL tokenURL,
+ Map extraHeaders)
+ throws OpenIdConnectRESTHelperException {
+
Map> params = new HashMap<>();
params.put("grant_type", Arrays.asList("client_credentials"));
try {
@@ -83,34 +100,41 @@ public class OpenIdConnectRESTHelper {
} catch (UnsupportedEncodingException e) {
logger.error("Cannot URL encode 'client_secret'", e);
}
- return performQueryTokenWithPOST(tokenURL, null, params);
+ return performQueryTokenWithPOST(tokenURL, null, params, extraHeaders);
}
public static JWTToken queryToken(String clientId, URL tokenURL, String code, String scope,
String redirectURI) throws Exception {
+ return queryToken(clientId, tokenURL, code, scope, redirectURI, null);
+ }
+
+ public static JWTToken queryToken(String clientId, URL tokenURL, String code, String scope,
+ String redirectURI, Map extraHeaders) throws Exception {
+
Map> params = new HashMap<>();
params.put("client_id", Arrays.asList(URLEncoder.encode(clientId, "UTF-8")));
params.put("grant_type", Arrays.asList("authorization_code"));
params.put("scope", Arrays.asList(URLEncoder.encode(scope, "UTF-8")));
params.put("code", Arrays.asList(URLEncoder.encode(code, "UTF-8")));
params.put("redirect_uri", Arrays.asList(URLEncoder.encode(redirectURI, "UTF-8")));
- return performQueryTokenWithPOST(tokenURL, null, params);
+ return performQueryTokenWithPOST(tokenURL, null, params, extraHeaders);
}
-
protected static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
Map> params) throws OpenIdConnectRESTHelperException {
- return performQueryTokenWithPOST(tokenURL, authorization, params, null);
+
+ return performQueryTokenWithPOST(tokenURL, authorization, params, null);
}
protected static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
- Map> params, Map headers) throws OpenIdConnectRESTHelperException {
+ Map> params, Map headers) throws OpenIdConnectRESTHelperException {
logger.debug("Querying access token from OIDC server with URL: {}", tokenURL);
StringBuilder sb;
try {
- HttpURLConnection httpURLConnection = performURLEncodedPOSTSendData(tokenURL, params, authorization, headers);
+ HttpURLConnection httpURLConnection = performURLEncodedPOSTSendData(tokenURL, params, authorization,
+ headers);
sb = new StringBuilder();
int httpResultCode = httpURLConnection.getResponseCode();
@@ -149,12 +173,13 @@ public class OpenIdConnectRESTHelper {
}
protected static HttpURLConnection performURLEncodedPOSTSendData(URL url, Map> params,
- String authorization) throws IOException, ProtocolException, UnsupportedEncodingException {
+ String authorization) throws IOException, ProtocolException, UnsupportedEncodingException {
return performURLEncodedPOSTSendData(url, params, authorization, null);
}
protected static HttpURLConnection performURLEncodedPOSTSendData(URL url, Map> params,
- String authorization, Map headers) throws IOException, ProtocolException, UnsupportedEncodingException {
+ String authorization, Map headers)
+ throws IOException, ProtocolException, UnsupportedEncodingException {
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
@@ -188,7 +213,7 @@ public class OpenIdConnectRESTHelper {
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
* @param clientId the client id
* @param clientSecret the client secret
- * @param audience the audience (context) where to request the issuing of the ticket
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
* @param permissions a list of permissions, can be null
* @return the issued token
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
@@ -196,74 +221,37 @@ public class OpenIdConnectRESTHelper {
public static JWTToken queryUMAToken(URL tokenUrl, String clientId, String clientSecret, String audience,
List permissions) throws OpenIdConnectRESTHelperException {
- return queryUMAToken(tokenUrl,
- "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()),
- audience, permissions);
+ return queryUMAToken(tokenUrl, clientId, clientSecret, audience, permissions, null);
}
/**
- * Queries from the OIDC server an exchanged token by using provided access token, for the given audience (context),
- * in URLEncoded form or not, and optionally a list of permissions.
+ * Queries from the OIDC server an UMA token, by using provided clientId and client secret for the given audience
+ * (context), in URLEncoded form or not, and optionally a list of permissions.
*
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
- * @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
- * @param audience the audience (context) where to request the issuing of the ticket (URLEncoded)
+ * @param clientId the client id
+ * @param clientSecret the client secret
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
* @param permissions a list of permissions, can be null
+ * @param extraHeaders extra HTTP headers to add to the request (e.g. X-D4Science-Context
custom header), may be null
* @return the issued token
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
*/
- public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String client_id, String client_secret,
- List permissions) throws OpenIdConnectRESTHelperException {
+ public static JWTToken queryUMAToken(URL tokenUrl, String clientId, String clientSecret, String audience,
+ List permissions, Map extraHeaders) throws OpenIdConnectRESTHelperException {
- logger.info("Queried exchangeToken for context " + audience);
-
- Map> params = new HashMap<>();
-
- params.put("subject_token", Arrays.asList(authorization));
- params.put("client_id", Arrays.asList(client_id));
- params.put("client_secret", Arrays.asList(client_secret));
- params.put("grant_type", Arrays.asList("urn:ietf:params:oauth:grant-type:token-exchange"));
- params.put("subject_token_type", Arrays.asList("urn:ietf:params:oauth:token-type:access_token"));
- params.put("requested_token_type", Arrays.asList("urn:ietf:params:oauth:token-type:access_token"));
-
- if (audience.startsWith("/")) {
- try {
- logger.trace("Audience was provided in non URL encoded form, encoding it");
- audience = URLEncoder.encode(audience, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- logger.error("Cannot URL encode 'audience'", e);
- }
- }
- try {
- params.put("audience", Arrays.asList(URLEncoder.encode(audience, "UTF-8")));
- } catch (UnsupportedEncodingException e) {
- logger.error("Cannot URL encode 'audience'", e);
- }
- if (permissions != null && !permissions.isEmpty()) {
- params.put(
- "permission", permissions.stream().map(s -> {
- try {
- return URLEncoder.encode(s, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- return "";
- }
- }).collect(Collectors.toList()));
- }
-
-
- // Map headers = new HashMap<>();
- // headers.put("X-D4Science-Context", audience);
-
- return performQueryTokenWithPOST(tokenUrl, null, params/*, headers*/);
+ return queryUMAToken(tokenUrl,
+ "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()),
+ audience, permissions, extraHeaders);
}
-
+
/**
* Queries from the OIDC server an UMA token, by using provided access token, for the given audience (context),
* in URLEncoded form or not, and optionally a list of permissions.
*
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
* @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
- * @param audience the audience (context) where to request the issuing of the ticket (URLEncoded)
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
* @param permissions a list of permissions, can be null
* @return the issued token
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
@@ -271,6 +259,24 @@ public class OpenIdConnectRESTHelper {
public static JWTToken queryUMAToken(URL tokenUrl, String authorization, String audience,
List permissions) throws OpenIdConnectRESTHelperException {
+ return queryUMAToken(tokenUrl, authorization, audience, permissions, null);
+ }
+
+ /**
+ * Queries from the OIDC server an UMA token, by using provided access token, for the given audience (context),
+ * in URLEncoded form or not, and optionally a list of permissions.
+ *
+ * @param tokenUrl the token endpoint {@link URL} of the OIDC server
+ * @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not)
+ * @param permissions a list of permissions, can be null
+ * @param extraHeaders extra HTTP headers to add to the request (e.g. X-D4Science-Context
custom header), may be null
+ * @return the issued token
+ * @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
+ */
+ public static JWTToken queryUMAToken(URL tokenUrl, String authorization, String audience,
+ List permissions, Map extraHeaders) throws OpenIdConnectRESTHelperException {
+
Map> params = new HashMap<>();
params.put("grant_type", Arrays.asList("urn:ietf:params:oauth:grant-type:uma-ticket"));
if (audience.startsWith("/")) {
@@ -296,7 +302,104 @@ public class OpenIdConnectRESTHelper {
}
}).collect(Collectors.toList()));
}
- return performQueryTokenWithPOST(tokenUrl, authorization, params);
+ return performQueryTokenWithPOST(tokenUrl, authorization, params, extraHeaders);
+ }
+
+ /**
+ * Queries from the OIDC server an exchanged token by using provided access token, optionally for the given audience (context)
+ * in URLEncoded form or not.
+ *
+ * @param tokenUrl the token endpoint {@link URL} of the OIDC server
+ * @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not), may be null
+ * @param clientId the client id
+ * @param clientSecret the client secret
+ * @param extraHeaders extra HTTP headers to add to the request (e.g. X-D4Science-Context
custom header), may be null
+ * @return the issued token
+ * @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
+ */
+ public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String client_id,
+ String client_secret, Map extraHeaders) throws OpenIdConnectRESTHelperException {
+
+ return queryExchangeToken(tokenUrl, authorization, audience, client_id, client_secret,
+ "urn:ietf:params:oauth:token-type:access_token", null, extraHeaders);
+ }
+
+ /**
+ * Queries from the OIDC server an exchanged token by using provided access token, optionally for the given audience (context)
+ * in URLEncoded form or not.
+ *
+ * @param tokenUrl the token endpoint {@link URL} of the OIDC server
+ * @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not), may be null
+ * @param clientId the client id
+ * @param clientSecret the client secret
+ * @param withRefreshToken request also the refresh token (forced to true
for offline requests)
+ * @param offline request a refresh token of offline type (TYP claim)
+ * @param extraHeaders extra HTTP headers to add to the request (e.g. X-D4Science-Context
custom header), may be null
+ * @return the issued token
+ * @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
+ */
+ public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String clientId,
+ String clientSecret, boolean withRefreshToken, boolean offline, Map extraHeaders)
+ throws OpenIdConnectRESTHelperException {
+
+ return queryExchangeToken(tokenUrl, authorization, audience, clientId, clientSecret,
+ withRefreshToken || offline ? "urn:ietf:params:oauth:token-type:refresh_token"
+ : "urn:ietf:params:oauth:token-type:access_token",
+ offline ? "offline_access" : null, extraHeaders);
+ }
+
+ /**
+ * Queries from the OIDC server an exchanged token by using provided access token, optionally for the given audience (context)
+ * in URLEncoded form or not.
+ *
+ * @param tokenUrl the token endpoint {@link URL} of the OIDC server
+ * @param authorization the auth token (the access token URLEncoded by the "Bearer " string)
+ * @param audience the audience (context) where to request the issuing of the token (URLEncoded or not), may be null
+ * @param clientId the client id
+ * @param clientSecret the client secret
+ * @param requestedTokenType the requested token type (e.g. urn:ietf:params:oauth:token-type:refresh_token
for refresh token)
+ * @param scope the optional scope to request (e.g. offline_access
for an offline token)
+ * @param extraHeaders extra HTTP headers to add to the request (e.g. X-D4Science-Context
custom header), may be null
+ * @return the issued token
+ * @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
+ */
+ public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String clientId,
+ String clientSecret, String requestedTokenType, String scope, Map extraHeaders)
+ throws OpenIdConnectRESTHelperException {
+
+ logger.info("Querying exchange token for context: " + audience);
+
+ Map> params = new HashMap<>();
+
+ params.put("subject_token", Arrays.asList(authorization));
+ params.put("client_id", Arrays.asList(clientId));
+ params.put("client_secret", Arrays.asList(clientSecret));
+ params.put("grant_type", Arrays.asList("urn:ietf:params:oauth:grant-type:token-exchange"));
+ params.put("subject_token_type", Arrays.asList("urn:ietf:params:oauth:token-type:access_token"));
+ params.put("requested_token_type", Arrays.asList(requestedTokenType));
+ if (scope != null) {
+ params.put("scope", Arrays.asList(scope));
+ }
+
+ if (audience != null) {
+ if (audience.startsWith("/")) {
+ try {
+ logger.trace("Audience was provided in non URL encoded form, encoding it");
+ audience = URLEncoder.encode(audience, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ logger.error("Cannot URL encode 'audience'", e);
+ }
+ }
+ try {
+ params.put("audience", Arrays.asList(URLEncoder.encode(audience, "UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ logger.error("Cannot URL encode 'audience'", e);
+ }
+ }
+
+ return performQueryTokenWithPOST(tokenUrl, null, params, extraHeaders);
}
/**
@@ -322,6 +425,7 @@ public class OpenIdConnectRESTHelper {
*/
public static JWTToken refreshToken(URL tokenURL, String clientId, JWTToken token)
throws OpenIdConnectRESTHelperException {
+
return refreshToken(tokenURL, clientId, null, token);
}