package org.gcube.portlets.user.geoportaldataviewer.server.mongoservice.accessidentities; 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 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); 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); String umaAcessToken = null; String clientId = credentials.getClientId(); String clientSecret = credentials.getClientSecret(); try { LOG.info("Querying KeycloakClientFactory to get UMA token.."); TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(clientId, clientSecret, currentScope, null); umaAcessToken = tr.getAccessToken(); if (umaAcessToken != null && !umaAcessToken.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 { try { // Here the previousUMAToken should be null previousUMAToken = AccessTokenProvider.instance.get(); } catch (Exception e) { // catching excpetion to be sure // silent } LOG.debug("JWT token: " + umaAcessToken.substring(0, 20) + "_MASKED_TOKEN_"); LOG.info("Setting clientId '" + clientId + "' identity by JWT token in the " + AccessTokenProvider.class.getSimpleName()); AccessTokenProvider.instance.set(umaAcessToken); } catch (Exception e) { LOG.error(e.getMessage(), e); throw new Exception(e.getMessage()); } } @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"); } } }