From 65e2882c2f5fec2c4f964db967b36c94168ac94d Mon Sep 17 00:00:00 2001 From: Mauro Mugnaini Date: Mon, 29 Jun 2020 16:22:51 +0200 Subject: [PATCH] Refactoring of common code and new mthods to get "refreshed" token --- .../oidc/rest/OpenIdConnectRESTHelper.java | 119 ++++++++++++------ 1 file changed, 81 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java b/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java index 0220c28..b220716 100644 --- a/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java +++ b/src/main/java/org/gcube/oidc/rest/OpenIdConnectRESTHelper.java @@ -6,6 +6,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; +import java.net.ProtocolException; import java.net.URL; import java.net.URLEncoder; import java.util.Arrays; @@ -72,6 +73,35 @@ public class OpenIdConnectRESTHelper { if (logger.isDebugEnabled()) { logger.debug("Querying access token from OIDC server with URL: " + tokenURL); } + HttpURLConnection httpURLConnection = performURLEncodedPOSTSendData(tokenURL, params, authorization); + + StringBuilder sb = new StringBuilder(); + int httpResultCode = httpURLConnection.getResponseCode(); + if (logger.isTraceEnabled()) { + logger.trace("HTTP Response code: " + httpResultCode); + } + if (httpResultCode != HttpURLConnection.HTTP_OK) { + BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getErrorStream(), "UTF-8")); + String line = null; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + throw new Exception("Unable to get token " + sb); + } else { + BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8")); + String line = null; + while ((line = br.readLine()) != null) { + sb.append(line + "\n"); + } + br.close(); + } + return JWTToken.fromString(sb.toString()); + } + + protected static HttpURLConnection performURLEncodedPOSTSendData(URL tokenURL, Map> params, + String authorization) throws IOException, ProtocolException, UnsupportedEncodingException { + HttpURLConnection con = (HttpURLConnection) tokenURL.openConnection(); con.setRequestMethod("POST"); con.setDoOutput(true); @@ -80,7 +110,7 @@ public class OpenIdConnectRESTHelper { con.setRequestProperty("Accept", "application/json"); if (authorization != null) { if (logger.isDebugEnabled()) { - logger.debug("Adding auhotization header as: " + authorization); + logger.debug("Adding authorization header as: " + authorization); } con.setRequestProperty("Authorization", authorization); } @@ -90,29 +120,7 @@ public class OpenIdConnectRESTHelper { } os.write(mapToQueryString(params).getBytes("UTF-8")); os.close(); - - StringBuilder sb = new StringBuilder(); - int httpResultCode = con.getResponseCode(); - if (logger.isTraceEnabled()) { - logger.trace("HTTP Response code: " + httpResultCode); - } - if (httpResultCode != HttpURLConnection.HTTP_OK) { - BufferedReader br = new BufferedReader(new InputStreamReader(con.getErrorStream(), "UTF-8")); - String line = null; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - br.close(); - throw new Exception("Unable to get token " + sb); - } else { - BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); - String line = null; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - br.close(); - } - return JWTToken.fromString(sb.toString()); + return con; } public static JWTToken queryUMAToken(URL tokenUrl, String authorizationToken, String audience, @@ -134,27 +142,62 @@ public class OpenIdConnectRESTHelper { return performQueryTokenWithPOST(tokenUrl, authorizationToken, params); } - public static void logout(JWTToken token, URL logoutUrl, String clientId) throws IOException { + public static JWTToken refreshToken(URL tokenURL, JWTToken token) throws Exception { + return refreshToken(tokenURL, null, null, token); + } + + public static JWTToken refreshToken(URL tokenURL, String clientId, JWTToken token) throws Exception { + return refreshToken(tokenURL, clientId, null, token); + } + + public static JWTToken refreshToken(URL tokenURL, String clientId, String clientSecret, JWTToken token) + throws Exception { + Map> params = new HashMap<>(); + params.put("grant_type", Arrays.asList("refresh_token")); + if (clientId == null) { + clientId = getFirstAudienceNoAccount(token); + } + params.put("client_id", Arrays.asList(URLEncoder.encode(clientId, "UTF-8"))); + if (clientSecret != null) { + params.put("client_secret", Arrays.asList(URLEncoder.encode(clientSecret, "UTF-8"))); + } + params.put("refresh_token", Arrays.asList(token.getRefreshTokenString())); + return performQueryTokenWithPOST(tokenURL, null, params); + } + + private static String getFirstAudienceNoAccount(JWTToken token) { + // Trying to get it from the token's audience ('aud' field), getting the first except the 'account' + List tokenAud = token.getAud(); + tokenAud.remove(JWTToken.ACCOUNT_RESOURCE); + if (tokenAud.size() > 0) { + return tokenAud.iterator().next(); + } else { + // Setting it to empty string to avoid NPE in encoding + return ""; + } + } + + public static boolean logout(URL logoutUrl, JWTToken token) throws IOException { + return logout(logoutUrl, null, token); + } + + public static boolean logout(URL logoutUrl, String clientId, JWTToken token) throws IOException { + Map> params = new HashMap<>(); + if (clientId == null) { + clientId = getFirstAudienceNoAccount(token); + } params.put("client_id", Arrays.asList(URLEncoder.encode(clientId, "UTF-8"))); params.put("refresh_token", Arrays.asList(token.getRefreshTokenString())); logger.info("Performing logut from OIDC server with URL: " + logoutUrl); - HttpURLConnection con = (HttpURLConnection) logoutUrl.openConnection(); - con.setRequestMethod("POST"); - con.setDoOutput(true); - con.setDoInput(true); - con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - con.setRequestProperty("Accept", "application/json"); - con.setRequestProperty("Authorization", token.getAsBearer()); - OutputStream os = con.getOutputStream(); - os.write(mapToQueryString(params).getBytes("UTF-8")); - os.close(); - int responseCode = con.getResponseCode(); + HttpURLConnection httpURLConnection = performURLEncodedPOSTSendData(logoutUrl, params, token.getAsBearer()); + int responseCode = httpURLConnection.getResponseCode(); if (responseCode == 204) { logger.info("Logout performed correctly"); + return true; } else { - logger.error("Cannot perfrom logout: [" + responseCode + "] " + con.getResponseMessage()); + logger.error("Cannot perfrom logout: [" + responseCode + "] " + httpURLConnection.getResponseMessage()); } - + return false; } } \ No newline at end of file