exchange uses custom context header instead of audience parameter
This commit is contained in:
parent
c0f90cc895
commit
99358c1f62
|
@ -1,6 +1,12 @@
|
||||||
package org.gcube.portlets.admin;
|
package org.gcube.portlets.admin;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.ProtocolException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -18,24 +24,30 @@ import org.slf4j.LoggerFactory;
|
||||||
public class OpenIdConnectRESTHelperExtended extends OpenIdConnectRESTHelper {
|
public class OpenIdConnectRESTHelperExtended extends OpenIdConnectRESTHelper {
|
||||||
protected static final Logger logger = LoggerFactory.getLogger(OpenIdConnectRESTHelperExtended.class);
|
protected static final Logger logger = LoggerFactory.getLogger(OpenIdConnectRESTHelperExtended.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries from the OIDC server an exchanged token by using provided access token, for the given audience (context),
|
* 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.
|
* in URLEncoded form or not, and optionally a list of permissions.
|
||||||
*
|
*
|
||||||
* @param tokenUrl the token endpoint {@link URL} of the OIDC server
|
* @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 authorization the auth token (the access token URLEncoded by the
|
||||||
* @param audience the audience (context) where to request the issuing of the ticket (URLEncoded)
|
* "Bearer " string)
|
||||||
* @param permissions a list of permissions, can be <code>null</code>
|
* @param audience the audience (context) where to request the issuing of
|
||||||
|
* the ticket (URLEncoded)
|
||||||
|
* @param permissions a list of permissions, can be <code>null</code>
|
||||||
* @return the issued token
|
* @return the issued token
|
||||||
* @throws OpenIdConnectRESTHelperException if an error occurs (also an unauthorized call), inspect the exception for details
|
* @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,
|
public static JWTToken queryExchangeToken(URL tokenUrl, String authorization, String audience, String client_id,
|
||||||
|
String client_secret,
|
||||||
List<String> permissions) throws OpenIdConnectRESTHelperException {
|
List<String> permissions) throws OpenIdConnectRESTHelperException {
|
||||||
|
|
||||||
logger.info("Queried exchangeToken for context " + audience);
|
logger.info("Queried exchangeToken for context " + audience);
|
||||||
|
|
||||||
Map<String, List<String>> params = new HashMap<>();
|
Map<String, List<String>> params = new HashMap<>();
|
||||||
|
Map<String, String> extraHeaders = new HashMap<>();
|
||||||
|
|
||||||
params.put("subject_token", Arrays.asList(authorization));
|
params.put("subject_token", Arrays.asList(authorization));
|
||||||
params.put("client_id", Arrays.asList(client_id));
|
params.put("client_id", Arrays.asList(client_id));
|
||||||
|
@ -46,17 +58,20 @@ public class OpenIdConnectRESTHelperExtended extends OpenIdConnectRESTHelper {
|
||||||
|
|
||||||
if (audience.startsWith("/")) {
|
if (audience.startsWith("/")) {
|
||||||
try {
|
try {
|
||||||
logger.trace("Audience was provided in non URL encoded form, encoding it");
|
// logger.trace("Audience was provided in non URL encoded form, encoding it");
|
||||||
audience = URLEncoder.encode(audience, "UTF-8");
|
audience = URLEncoder.encode(audience, "UTF-8");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
logger.error("Cannot URL encode 'audience'", e);
|
logger.error("Cannot URL encode 'audience'", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
params.put("audience", Arrays.asList(URLEncoder.encode(audience, "UTF-8")));
|
extraHeaders.put("X-D4Science-Context", audience);
|
||||||
} 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()) {
|
if (permissions != null && !permissions.isEmpty()) {
|
||||||
params.put(
|
params.put(
|
||||||
"permission", permissions.stream().map(s -> {
|
"permission", permissions.stream().map(s -> {
|
||||||
|
@ -68,6 +83,86 @@ public class OpenIdConnectRESTHelperExtended extends OpenIdConnectRESTHelper {
|
||||||
}).collect(Collectors.toList()));
|
}).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return performQueryTokenWithPOST(tokenUrl, null, params);
|
// logger.info("Query exchangeToken, url " + tokenUrl);
|
||||||
|
// logger.info("Query exchangeToken, params " + params);
|
||||||
|
// logger.info("Query exchangeToken, extraHeaders " + extraHeaders);
|
||||||
|
|
||||||
|
return performQueryTokenWithPOST(tokenUrl, null, params, extraHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static JWTToken performQueryTokenWithPOST(URL tokenURL, String authorization,
|
||||||
|
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);
|
||||||
|
|
||||||
|
sb = new StringBuilder();
|
||||||
|
int httpResultCode = httpURLConnection.getResponseCode();
|
||||||
|
logger.trace("HTTP Response code: {}", httpResultCode);
|
||||||
|
String responseContentType = httpURLConnection.getContentType();
|
||||||
|
if (responseContentType != null) {
|
||||||
|
// logger.debug("Response content type is: {}", responseContentType);
|
||||||
|
} else {
|
||||||
|
responseContentType = "";
|
||||||
|
}
|
||||||
|
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 OpenIdConnectRESTHelperException.create("Unable to get token", httpResultCode,
|
||||||
|
responseContentType, sb.toString());
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new OpenIdConnectRESTHelperException("Unable to get the token", e);
|
||||||
|
}
|
||||||
|
return JWTToken.fromString(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HttpURLConnection performURLEncodedPOSTSendData(URL url, Map<String, List<String>> params,
|
||||||
|
String authorization, Map<String, String> headers)
|
||||||
|
throws IOException, ProtocolException, UnsupportedEncodingException {
|
||||||
|
|
||||||
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||||
|
con.setRequestMethod("POST");
|
||||||
|
con.setDoOutput(true);
|
||||||
|
con.setDoInput(true);
|
||||||
|
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
con.setRequestProperty("Accept", "application/json");
|
||||||
|
if (authorization != null) {
|
||||||
|
// logger.debug("Adding authorization header as: {}", authorization);
|
||||||
|
con.setRequestProperty("Authorization", authorization);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers != null) {
|
||||||
|
for (String key : headers.keySet()) {
|
||||||
|
con.setRequestProperty(key, headers.get(key));
|
||||||
|
// logger.info("setting header " + key + " : " + headers.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OutputStream os = con.getOutputStream();
|
||||||
|
|
||||||
|
String queryString = mapToQueryString(params);
|
||||||
|
// logger.debug("Parameters query string is: {}", queryString);
|
||||||
|
os.write(queryString.getBytes("UTF-8"));
|
||||||
|
os.close();
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.gcube.portlets.admin;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -14,14 +13,11 @@ import javax.portlet.ResourceRequest;
|
||||||
import javax.portlet.ResourceResponse;
|
import javax.portlet.ResourceResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
import org.gcube.common.portal.PortalContext;
|
import org.gcube.common.portal.PortalContext;
|
||||||
import org.gcube.common.scope.impl.ScopeBean;
|
import org.gcube.common.scope.impl.ScopeBean;
|
||||||
import org.gcube.common.scope.impl.ScopeBean.Type;
|
import org.gcube.common.scope.impl.ScopeBean.Type;
|
||||||
import org.gcube.oidc.rest.JWTToken;
|
import org.gcube.oidc.rest.JWTToken;
|
||||||
import org.gcube.oidc.rest.OpenIdConnectConfiguration;
|
import org.gcube.oidc.rest.OpenIdConnectConfiguration;
|
||||||
import org.gcube.oidc.rest.OpenIdConnectRESTHelper;
|
|
||||||
//import org.gcube.oidc.rest.OpenIdConnectRESTHelper;
|
//import org.gcube.oidc.rest.OpenIdConnectRESTHelper;
|
||||||
import org.gcube.oidc.rest.OpenIdConnectRESTHelperException;
|
import org.gcube.oidc.rest.OpenIdConnectRESTHelperException;
|
||||||
import org.gcube.portal.oidc.lr62.JWTCacheProxy;
|
import org.gcube.portal.oidc.lr62.JWTCacheProxy;
|
||||||
|
@ -30,9 +26,9 @@ import org.gcube.vomanagement.usermanagement.GroupManager;
|
||||||
import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager;
|
import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager;
|
||||||
import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
|
import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
|
||||||
|
|
||||||
|
import com.liferay.portal.kernel.json.JSONArray;
|
||||||
import com.liferay.portal.kernel.json.JSONFactoryUtil;
|
import com.liferay.portal.kernel.json.JSONFactoryUtil;
|
||||||
import com.liferay.portal.kernel.json.JSONObject;
|
import com.liferay.portal.kernel.json.JSONObject;
|
||||||
import com.liferay.portal.kernel.json.JSONArray;
|
|
||||||
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
||||||
import com.liferay.portal.kernel.util.ParamUtil;
|
import com.liferay.portal.kernel.util.ParamUtil;
|
||||||
import com.liferay.portal.model.User;
|
import com.liferay.portal.model.User;
|
||||||
|
@ -95,7 +91,7 @@ public class RPTTokenReader extends MVCPortlet {
|
||||||
System.out.println("Selected context=" + context);
|
System.out.println("Selected context=" + context);
|
||||||
HttpServletRequest httpReq = PortalUtil
|
HttpServletRequest httpReq = PortalUtil
|
||||||
.getOriginalServletRequest(PortalUtil.getHttpServletRequest(resourceRequest));
|
.getOriginalServletRequest(PortalUtil.getHttpServletRequest(resourceRequest));
|
||||||
JWTToken umaToken = null;
|
// JWTToken umaToken = null;
|
||||||
JWTToken exchangedToken = null;
|
JWTToken exchangedToken = null;
|
||||||
|
|
||||||
GroupManager gm = new LiferayGroupManager();
|
GroupManager gm = new LiferayGroupManager();
|
||||||
|
@ -120,12 +116,13 @@ public class RPTTokenReader extends MVCPortlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
JWTToken authToken = jwtCacheProxy.getOIDCToken(theUser, sessionId);
|
JWTToken authToken = jwtCacheProxy.getOIDCToken(theUser, sessionId);
|
||||||
umaToken = OpenIdConnectRESTHelper.queryUMAToken(configuration.getTokenURL(),
|
|
||||||
authToken.getAccessTokenAsBearer(), urlEncodedContext, null);
|
// umaToken = OpenIdConnectRESTHelper.queryUMAToken(configuration.getTokenURL(),
|
||||||
|
// authToken.getAccessTokenAsBearer(), urlEncodedContext, null);
|
||||||
|
|
||||||
// URL auth_url = configuration.getTokenURL();
|
// URL auth_url = configuration.getTokenURL();
|
||||||
// log.info("auth_url " + auth_url);
|
// log.info("auth_url " + auth_url);
|
||||||
// log.info("authToken " + authToken.getAccessTokenString());
|
log.info("authToken '" + authToken.getAccessTokenString() + "'");
|
||||||
// log.info("umaToken " + umaToken.getAccessTokenString());
|
// log.info("umaToken " + umaToken.getAccessTokenString());
|
||||||
// log.info("context " + context);
|
// log.info("context " + context);
|
||||||
// log.info("encoded_context " + urlEncodedContext);
|
// log.info("encoded_context " + urlEncodedContext);
|
||||||
|
@ -134,13 +131,13 @@ public class RPTTokenReader extends MVCPortlet {
|
||||||
|
|
||||||
exchangedToken = OpenIdConnectRESTHelperExtended.queryExchangeToken(
|
exchangedToken = OpenIdConnectRESTHelperExtended.queryExchangeToken(
|
||||||
configuration.getTokenURL(),
|
configuration.getTokenURL(),
|
||||||
umaToken.getAccessTokenString(),
|
authToken.getAccessTokenString(),
|
||||||
urlEncodedContext,
|
urlEncodedContext,
|
||||||
configuration.getPortalClientId(),
|
configuration.getPortalClientId(),
|
||||||
configuration.getPortalClientSecret(),
|
configuration.getPortalClientSecret(),
|
||||||
null);
|
null
|
||||||
|
);
|
||||||
|
|
||||||
// log.info("exchangedToken " + exchangedToken.getAccessTokenString());
|
// log.info("exchangedToken " + exchangedToken.getAccessTokenString());
|
||||||
|
|
||||||
// log.debug("Got a new UMA token " + exchangedToken.getTokenEssentials());
|
// log.debug("Got a new UMA token " + exchangedToken.getTokenEssentials());
|
||||||
|
@ -162,15 +159,6 @@ public class RPTTokenReader extends MVCPortlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
|
|
||||||
// jsonObject.put("success", false);
|
|
||||||
// jsonObject.put("comment", e.getMessage());
|
|
||||||
// resourceResponse.getWriter().println(jsonObject);
|
|
||||||
// super.serveResource(resourceRequest, resourceResponse);
|
|
||||||
// }
|
|
||||||
|
|
||||||
jsonObject.put("success", true);
|
jsonObject.put("success", true);
|
||||||
jsonObject.put("access_token", exchangedToken.getAccessTokenString());
|
jsonObject.put("access_token", exchangedToken.getAccessTokenString());
|
||||||
jsonObject.put("refresh_token", exchangedToken.getRefreshTokenString());
|
jsonObject.put("refresh_token", exchangedToken.getRefreshTokenString());
|
||||||
|
@ -180,7 +168,7 @@ public class RPTTokenReader extends MVCPortlet {
|
||||||
jsonObject.put("access_token_exp", exchangedToken.getExp());
|
jsonObject.put("access_token_exp", exchangedToken.getExp());
|
||||||
jsonObject.put("essential", exchangedToken.getTokenEssentials());
|
jsonObject.put("essential", exchangedToken.getTokenEssentials());
|
||||||
|
|
||||||
jsonObject.put("client_id", umaToken.getAzp());
|
jsonObject.put("client_id", exchangedToken.getAzp());
|
||||||
|
|
||||||
JSONArray audiences = JSONFactoryUtil.createJSONArray();
|
JSONArray audiences = JSONFactoryUtil.createJSONArray();
|
||||||
List<String> list_audiences = exchangedToken.getAud();
|
List<String> list_audiences = exchangedToken.getAud();
|
||||||
|
|
Loading…
Reference in New Issue