Removed `permission` list from exchange method signature and improved it adding also `refresh-token` as requested token type and `offline_access` scope. Added also extra headers support for all the token methods.
This commit is contained in:
parent
6da3a9f55a
commit
098bfc9fef
|
@ -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. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @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<String, String> extraHeaders)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
Map<String, List<String>> 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<String, String> extraHeaders) throws Exception {
|
||||
|
||||
Map<String, List<String>> 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<String, List<String>> params) throws OpenIdConnectRESTHelperException {
|
||||
return performQueryTokenWithPOST(tokenURL, authorization, params, null);
|
||||
|
||||
return performQueryTokenWithPOST(tokenURL, authorization, params, null);
|
||||
}
|
||||
|
||||
protected static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
|
||||
Map<String, List<String>> params, Map<String, String> headers) throws OpenIdConnectRESTHelperException {
|
||||
Map<String, List<String>> params, Map<String, String> 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<String, List<String>> 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<String, List<String>> params,
|
||||
String authorization, Map<String, String> headers) throws IOException, ProtocolException, UnsupportedEncodingException {
|
||||
String authorization, Map<String, String> 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 <code>null</code>
|
||||
* @return the issued token
|
||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
||||
|
@ -196,65 +221,28 @@ public class OpenIdConnectRESTHelper {
|
|||
public static JWTToken queryUMAToken(URL tokenUrl, String clientId, String clientSecret, String audience,
|
||||
List<String> 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 <code>null</code>
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @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<String> permissions) throws OpenIdConnectRESTHelperException {
|
||||
public static JWTToken queryUMAToken(URL tokenUrl, String clientId, String clientSecret, String audience,
|
||||
List<String> permissions, Map<String, String> extraHeaders) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
logger.info("Queried exchangeToken for context " + audience);
|
||||
|
||||
Map<String, List<String>> 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<String, String> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,7 +251,7 @@ public class OpenIdConnectRESTHelper {
|
|||
*
|
||||
* @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 <code>null</code>
|
||||
* @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<String> 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 <code>null</code>
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @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<String> permissions, Map<String, String> extraHeaders) throws OpenIdConnectRESTHelperException {
|
||||
|
||||
Map<String, List<String>> 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 <code>null</code>
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @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<String, String> 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 <code>null</code>
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param withRefreshToken request also the refresh token (forced to <code>true</code> 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. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @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<String, String> 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 <code>null</code>
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param requestedTokenType the requested token type (e.g. <code>urn:ietf:params:oauth:token-type:refresh_token</code> for refresh token)
|
||||
* @param scope the optional scope to request (e.g. <code>offline_access</code> for an offline token)
|
||||
* @param extraHeaders extra HTTP headers to add to the request (e.g. <code>X-D4Science-Context</code> custom header), may be <code>null</code>
|
||||
* @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<String, String> extraHeaders)
|
||||
throws OpenIdConnectRESTHelperException {
|
||||
|
||||
logger.info("Querying exchange token for context: " + audience);
|
||||
|
||||
Map<String, List<String>> 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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue