diff --git a/src/main/java/org/gcube/portal/threadlocalexec/SmartGearsPortalValve.java b/src/main/java/org/gcube/portal/threadlocalexec/SmartGearsPortalValve.java index 74ccca7..a58b41b 100644 --- a/src/main/java/org/gcube/portal/threadlocalexec/SmartGearsPortalValve.java +++ b/src/main/java/org/gcube/portal/threadlocalexec/SmartGearsPortalValve.java @@ -3,8 +3,6 @@ package org.gcube.portal.threadlocalexec; import static org.gcube.common.authorization.client.Constants.authorizationService; import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; @@ -23,12 +21,7 @@ import org.gcube.common.authorization.library.provider.UmaJWTProvider; import org.gcube.common.authorization.library.provider.UserInfo; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.oidc.rest.JWTToken; -import org.gcube.oidc.rest.OpenIdConnectConfiguration; -import org.gcube.oidc.rest.OpenIdConnectRESTHelper; -import org.gcube.oidc.rest.OpenIdConnectRESTHelperException; -import org.gcube.portal.oidc.lr62.JWTCacheProxy; -import org.gcube.portal.oidc.lr62.LiferayOpenIdConnectConfiguration; +import org.gcube.portal.oidc.lr62.OIDCUmaUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,14 +41,6 @@ public class SmartGearsPortalValve extends ValveBase { private final static String DEFAULT_ROLE = "OrganizationMember"; private final static String LIFERAY_POLLER_CONTEXT = "poller/receive"; - private static boolean REFRESH_UMA_TOKEN = false; - private static String LOGOUT_URI = "/c/portal/logout"; - private static boolean FORCE_LOGOUT_ON_INVALID_OIDC = true; - private static boolean FORCE_LOGOUT_ON_MISSING_OIDC = true; - private static boolean FORCE_LOGOUT_ON_OIDC_REFRESH_ERROR = true; - private static final int MAX_AUTHORIZATION_RETRY_ATTEMPTS = 4; - private static final int AUTHORIZATION_RETRY_ATTEMPTS_DELAY = 4000; - @Override public void invoke(Request req, Response resp) throws IOException, ServletException { SecurityTokenProvider.instance.reset(); @@ -83,7 +68,13 @@ public class SmartGearsPortalValve extends ValveBase { _log.error("Something went wrong in generating token for " + username + " in scope " + scope); e.printStackTrace(); } - checkUMATicket(request, (HttpServletResponse) resp, scope); + + _log.debug("Getting current user"); + User user = getCurrentUser(request); + _log.debug("Getting current session"); + HttpSession session = request.getSession(false); + OIDCUmaUtil.checkUMATicketAndProvideInThreadLocal(request, (HttpServletResponse) resp, user, + session, scope); //_log.trace("Security token set OK for " + username + " in scope " + scope); } @@ -92,223 +83,6 @@ public class SmartGearsPortalValve extends ValveBase { getNext().invoke(req, resp); } - private void checkUMATicket(HttpServletRequest request, HttpServletResponse response, String scope) { - _log.debug("Getting current user"); - User user = getCurrentUser(request); - if (user == null) { - _log.error("Current user not found, cannot continue"); - return; - } - _log.debug("Current user is: {} [{}]", user.getScreenName(), user.getEmailAddress()); - - HttpSession session = request.getSession(false); - if (session == null) { - _log.debug("Session is null, cannot continue"); - return; - } - String sessionId = session.getId(); - _log.debug("Current session ID is {}", sessionId); - String urlEncodedScope = null; - try { - urlEncodedScope = URLEncoder.encode(scope, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // Almost impossible - _log.error("Cannot URL encode scope", e); - return; - } - _log.debug("URL encoded scope is: {}", urlEncodedScope); - - JWTToken umaToken = null; - synchronized (JWTCacheProxy.getInstance().getMutexFor(user)) { - _log.trace("Getting UMA token for user {}, and session {}", user.getScreenName(), sessionId); - umaToken = JWTCacheProxy.getInstance().getUMAToken(user, sessionId); - if (umaToken != null && !umaToken.isExpired() && umaToken.getAud().contains(urlEncodedScope)) { - _log.trace("Current UMA token is OK {}", umaToken.getTokenEssentials()); - } else { - if (umaToken != null && umaToken.getAud().contains(urlEncodedScope) && umaToken.isExpired()) { - if (REFRESH_UMA_TOKEN) { - _log.debug("Suitable UMA token found but is expired, trying to refresh it {}", - umaToken.getTokenEssentials()); - - OpenIdConnectConfiguration configuration = LiferayOpenIdConnectConfiguration - .getConfiguration(request); - try { - umaToken = OpenIdConnectRESTHelper.refreshToken(configuration.getTokenURL(), umaToken); - _log.debug("Got a refreshed UMA token {}", umaToken.getTokenEssentials()); - - _log.debug("Setting the refreshed UMA token in cache proxy for user {}, and session]", - user.getScreenName(), sessionId); - - JWTCacheProxy.getInstance().setUMAToken(user, sessionId, umaToken); - } catch (OpenIdConnectRESTHelperException e) { - if (e.hasJSONPayload()) { - if (OpenIdConnectRESTHelper.isInvalidBearerTokenError(e.getResponseString())) { - if (FORCE_LOGOUT_ON_INVALID_OIDC) { - _log.warn("OIDC token is become invalid, forcing redirect to logout URI"); - forceLogout(response); - } else { - _log.warn("OIDC token is become invalid, cannot continue"); - } - return; - } else if (OpenIdConnectRESTHelper.isTokenNotActiveError(e.getResponseString())) { - _log.info("UMA token is no more active, get new one"); - } else { - _log.error("Other UMA token refresh error", e); - } - } else { - _log.error("Refreshing UMA token on server " + umaToken.getTokenEssentials(), e); - } - umaToken = null; - _log.debug( - "Removing inactive UMA token from cache proxy if present for user {} and session {}", - user.getScreenName(), sessionId); - - JWTCacheProxy.getInstance().removeUMAToken(user, sessionId); - } - } else { - _log.debug("Suitable UMA token found but it is expired." - + "It will be replaced with new one according to settings {}", - umaToken.getTokenEssentials()); - - umaToken = null; - _log.debug("Removing inactive UMA token from cache proxy if present for user {} and session {}", - user.getScreenName(), sessionId); - - JWTCacheProxy.getInstance().removeUMAToken(user, sessionId); - } - } - if (umaToken == null || !umaToken.getAud().contains(urlEncodedScope)) { - boolean scopeIsChanged = false; - if (umaToken == null) { - _log.debug("Getting new UMA token for scope {}", urlEncodedScope); - } else if (!umaToken.getAud().contains(urlEncodedScope)) { - scopeIsChanged = true; - _log.info("Getting new UMA token for scope {} since it has been issued for another scope {}", - urlEncodedScope, umaToken.getTokenEssentials()); - } - _log.debug("Getting OIDC token from cache proxy for user {} and session {}", user.getScreenName(), - sessionId); - - JWTToken authToken = JWTCacheProxy.getInstance().getOIDCToken(user, sessionId); - if (authToken == null) { - if (FORCE_LOGOUT_ON_MISSING_OIDC) { - _log.trace("OIDC token is null in cache proxy, force redirecting to logut URI"); - forceLogout(response); - } else { - _log.error("OIDC token is null in cache proxy, cannot continue!"); - } - return; - } else { - _log.debug("OIDC token is {}", authToken.getTokenEssentials()); - } - OpenIdConnectConfiguration configuration = LiferayOpenIdConnectConfiguration - .getConfiguration(request); - - boolean isNotAuthorized = false; - int authorizationAttempts = 0; - do { - try { - if (isNotAuthorized || scopeIsChanged || authToken.isExpired()) { - if (isNotAuthorized) { - _log.info( - "UMA token is not authorized with current OIDC token, " - + "refreshing it to be sure that new grants are present. " - + "[attempts: {}]", - authorizationAttempts); - - // Resetting the flag to be sure to have correct log message each loop - isNotAuthorized = false; - } else if (scopeIsChanged) { - _log.info( - "Scope is changed, refreshing token to be sure that new grants are present"); - } else if (authToken.isExpired()) { - _log.debug("OIDC token is expired, trying to refresh it {}", - authToken.getTokenEssentials()); - } - try { - authToken = OpenIdConnectRESTHelper.refreshToken(configuration.getTokenURL(), - authToken); - } catch (OpenIdConnectRESTHelperException e) { - if (FORCE_LOGOUT_ON_OIDC_REFRESH_ERROR) { - _log.warn("Error refreshing OIDC token, force redirecting to logut URI"); - forceLogout(response); - } else { - _log.error("Refreshing OIDC token on server", e); - } - return; - } - _log.debug("Setting refreshed OIDC token in cache proxy"); - JWTCacheProxy.getInstance().setOIDCToken(user, sessionId, authToken); - } - _log.info("Getting UMA token from OIDC endpoint for scope: " + urlEncodedScope); - umaToken = OpenIdConnectRESTHelper.queryUMAToken(configuration.getTokenURL(), - authToken.getAccessTokenAsBearer(), urlEncodedScope, null); - - _log.debug("Got new UMA token {}", umaToken.getTokenEssentials()); - } catch (OpenIdConnectRESTHelperException e) { - if (e.hasJSONPayload()) { - if (OpenIdConnectRESTHelper.isInvalidBearerTokenError(e.getResponseString())) { - if (FORCE_LOGOUT_ON_INVALID_OIDC) { - _log.warn("OIDC token is become invalid, forcing redirect to logout URI"); - forceLogout(response); - } else { - _log.error("OIDC token is become invalid, cannot continue"); - } - return; - } else if (OpenIdConnectRESTHelper - .isAccessDeniedNotAuthorizedError(e.getResponseString())) { - - _log.info("UMA token is" + (isNotAuthorized ? " still" : "") - + " not authorized with actual OIDC token"); - - isNotAuthorized = true; - authorizationAttempts += 1; - if (authorizationAttempts <= MAX_AUTHORIZATION_RETRY_ATTEMPTS) { - _log.debug("Sleeping " + AUTHORIZATION_RETRY_ATTEMPTS_DELAY - + " ms and looping refreshing the OIDC"); - try { - Thread.sleep(AUTHORIZATION_RETRY_ATTEMPTS_DELAY); - } catch (InterruptedException ie) { - ie.printStackTrace(); - } - } else { - _log.warn("OIDC token refresh attempts exhausted"); - return; - } - } - } else { - _log.error("Getting UMA token from server", e); - return; - } - } - } while (isNotAuthorized); - } - - _log.debug("Setting UMA token in cache proxy for user {} and session {}", user.getScreenName(), - sessionId); - - JWTCacheProxy.getInstance().setUMAToken(user, sessionId, umaToken); - } - } - - _log.trace("Current UMA token in use is: {}", umaToken.getTokenEssentials()); - - _log.debug("Setting UMA token with jti {} in UMA JWT provider", umaToken.getJti()); - UmaJWTProvider.instance.set(umaToken.getRaw()); - } - - protected void forceLogout(HttpServletResponse response) { - try { - if (!response.isCommitted()) { - response.sendRedirect(LOGOUT_URI); - } else { - _log.warn("Cannot redirect to logout URI since the response is already commited"); - } - } catch (IOException e) { - _log.error("Cannot redirect to logout URI: " + LOGOUT_URI, e); - } - } - /** * * @param context