package org.gcube.portlets.user.geoportaldataviewer.server.mongoservice.accessidentity; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.gcube.common.authorization.library.provider.AccessTokenProvider; import org.gcube.common.keycloak.KeycloakClientFactory; import org.gcube.common.keycloak.model.TokenResponse; import org.gcube.portlets.user.geoportaldataviewer.server.mongoservice.IAMClientCredentialsReader; import org.gcube.portlets.user.geoportaldataviewer.server.util.SessionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class IAMClientIdentity implements GcubeIdentity { private static final Logger LOG = LoggerFactory.getLogger(IAMClientIdentity.class); private String previousUMAToken = null; private String currentUMAToken = null; private String clientId = null; private static final String IAM_CLIENT_CREDENTIALS = "IAM_CLIENT_CREDENTIALS"; @Override public void setIdentity(HttpServletRequest httpRequest) throws Exception { LOG.info("setIdentity called"); String currentScope = SessionUtil.getCurrentContext(httpRequest, true); LOG.info("the scope is {}", currentScope); IAMClientCredentials credentials = sessionGetIAMClientCredentials(httpRequest); try { if (credentials == null) { credentials = IAMClientCredentialsReader.getCredentials(); sessionSetIAMClientCredentials(httpRequest, credentials); } } catch (Exception e) { LOG.error("Error on discovering IAM Client credentials", e); throw new Exception("IAM Client discovery failed"); } LOG.trace("Read credentials: " + credentials); clientId = credentials.getClientId(); String clientSecret = credentials.getClientSecret(); try { LOG.info("Querying KeycloakClientFactory to get UMA token.."); TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(currentScope, clientId, clientSecret, currentScope, null); currentUMAToken = tr.getAccessToken(); if (currentUMAToken != null && !currentUMAToken.isEmpty()) { LOG.info("UMA Access Token read correctly"); } else { LOG.error("UMA Access Token NOT RETRIEVED!!!"); throw new Exception("UMA Access Token is null or empty"); } } catch (Exception e2) { throw new Exception("Error occurred on reading UMA access token:", e2); } try { LOG.debug("JWT token: " + currentUMAToken.substring(0, 20) + "_MASKED_TOKEN_"); try { // Here the previousUMAToken should be null previousUMAToken = AccessTokenProvider.instance.get(); } catch (Exception e) { // catching excpetion to be sure // silent } LOG.info("Setting clientId '" + clientId + "' identity by JWT token in the " + AccessTokenProvider.class.getSimpleName()); AccessTokenProvider.instance.set(currentUMAToken); } catch (Exception e) { LOG.error(e.getMessage(), e); throw new Exception(e.getMessage()); } } @Override public String getToken() { return currentUMAToken; } @Override public void resetIdentity() { LOG.info("resetIdentity called"); AccessTokenProvider.instance.set(previousUMAToken); LOG.info("resetIdentity to previous AccessToken"); } /** * Gets the IAM client credentials. * * @param httpRequest the http request * @return the IAM client credentials */ public static IAMClientCredentials sessionGetIAMClientCredentials(HttpServletRequest httpRequest) { HttpSession session = httpRequest.getSession(); try { return (IAMClientCredentials) session.getAttribute(IAM_CLIENT_CREDENTIALS); } catch (Exception e) { LOG.warn("Error occurred when reading " + IAM_CLIENT_CREDENTIALS + " from session"); return null; } } /** * Sets the IAM client credentials. * * @param httpRequest the http request * @param iamCC the iam CC */ public static void sessionSetIAMClientCredentials(HttpServletRequest httpRequest, IAMClientCredentials iamCC) { HttpSession session = httpRequest.getSession(); try { session.setAttribute(IAM_CLIENT_CREDENTIALS, iamCC); } catch (Exception e) { LOG.warn("Error occurred when setting " + IAM_CLIENT_CREDENTIALS + " into session"); } } @Override public String getIdentityDescription() { return "ClientId: " + clientId; } @Override public String getIdentity() { return clientId; } }