From d3ed5b174d21cefaafe8745f4c3691ce6c83b74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandeep=20Mor=C3=A9?= Date: Fri, 29 Jul 2022 14:22:03 -0400 Subject: [PATCH] Checkpoint --- gateway-provider-security-pac4j/pom.xml | 17 ++++++- .../pac4j/filter/Pac4jDispatcherFilter.java | 9 ++-- .../pac4j/filter/Pac4jIdentityAdapter.java | 14 +++--- .../pac4j/session/KnoxSessionStore.java | 44 ++++++++++++------- .../knox/gateway/pac4j/Pac4jProviderTest.java | 11 +++++ pom.xml | 16 ++++--- 6 files changed, 76 insertions(+), 35 deletions(-) diff --git a/gateway-provider-security-pac4j/pom.xml b/gateway-provider-security-pac4j/pom.xml index 44d46d0f1d..13753094f9 100644 --- a/gateway-provider-security-pac4j/pom.xml +++ b/gateway-provider-security-pac4j/pom.xml @@ -84,6 +84,12 @@ org.pac4j pac4j-cas + + + com.sun.istack + istack-commons-runtime + + org.pac4j @@ -119,7 +125,7 @@ org.pac4j - pac4j-saml-opensamlv3 + pac4j-saml ch.qos.logback @@ -143,6 +149,15 @@ + + org.pac4j + pac4j-jee + + + net.shibboleth.utilities + java-support + + diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java index 037b97aa35..a8c6fa7376 100644 --- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java +++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java @@ -219,12 +219,10 @@ public void init( FilterConfig filterConfig ) throws ServletException { } - callbackFilter = new CallbackFilter(); + callbackFilter = new CallbackFilter(config); callbackFilter.init(filterConfig); - callbackFilter.setConfigOnly(config); - securityFilter = new SecurityFilter(); + securityFilter = new SecurityFilter(config); securityFilter.setClients(clientName); - securityFilter.setConfigOnly(config); final String domainSuffix = filterConfig.getInitParameter(PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM); final String sessionStoreVar = filterConfig.getInitParameter(PAC4J_SESSION_STORE); @@ -232,7 +230,8 @@ public void init( FilterConfig filterConfig ) throws ServletException { SessionStore sessionStore; if(!StringUtils.isBlank(sessionStoreVar) && JEESessionStore.class.getName().contains(sessionStoreVar) ) { - sessionStore = new JEESessionStore(); + /* NOTE: this is a final variable, and will be used by all requests in Knox */ + sessionStore = JEESessionStore.INSTANCE; } else { sessionStore = new KnoxSessionStore(cryptoService, clusterName, domainSuffix, sessionStoreConfigs); } diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java index 82864e1f91..85a5f2b863 100644 --- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java +++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java @@ -31,8 +31,8 @@ import org.apache.logging.log4j.Logger; import org.pac4j.core.config.Config; import org.pac4j.core.context.JEEContext; -import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; +import org.pac4j.core.profile.UserProfile; import javax.security.auth.Subject; import javax.servlet.Filter; @@ -84,14 +84,14 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo final HttpServletRequest request = (HttpServletRequest) servletRequest; final HttpServletResponse response = (HttpServletResponse) servletResponse; - final JEEContext context = new JEEContext(request, response, - ((Config)request.getAttribute(PAC4J_CONFIG)).getSessionStore()); - final ProfileManager manager = new ProfileManager<>(context); - final Optional optional = manager.get(true); + final JEEContext context = new JEEContext(request, response); + /* see https://www.pac4j.org/blog/what_s_new_in_pac4j_v5.html#4-session-management */ + final ProfileManager manager = new ProfileManager(context, ((Config)request.getAttribute(PAC4J_CONFIG)).getSessionStore()); + final Optional optional = manager.getProfile(); if (optional.isPresent()) { - CommonProfile profile = optional.get(); + UserProfile profile = optional.get(); logger.debug("User authenticated as: {}", profile); - manager.remove(true); + manager.removeProfiles(); String id = null; if (idAttribute != null) { Object attribute = profile.getAttribute(idAttribute); diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java index 040c82d3e3..760ab3e9f9 100644 --- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java +++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java @@ -26,15 +26,16 @@ import org.apache.knox.gateway.util.Urls; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.pac4j.core.context.ContextHelper; +import org.pac4j.core.context.WebContextHelper; import org.pac4j.core.context.Cookie; import org.pac4j.core.context.JEEContext; import org.pac4j.core.context.WebContext; import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.exception.TechnicalException; import org.pac4j.core.profile.CommonProfile; -import org.pac4j.core.util.JavaSerializationHelper; import org.pac4j.core.util.Pac4jConstants; +import org.pac4j.core.util.serializer.JavaSerializer; +import org.pac4j.core.util.serializer.Serializer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -63,7 +64,7 @@ * * @since 0.8.0 */ -public class KnoxSessionStore implements SessionStore { +public class KnoxSessionStore implements SessionStore { private static final Logger logger = LogManager.getLogger(KnoxSessionStore.class); @@ -71,8 +72,6 @@ public class KnoxSessionStore implements SessionStore { public static final String PAC4J_SESSION_PREFIX = "pac4j.session."; - private final JavaSerializationHelper javaSerializationHelper; - private final CryptoService cryptoService; private final String clusterName; @@ -81,6 +80,8 @@ public class KnoxSessionStore implements SessionStore { final Map sessionStoreConfigs; + private Serializer serializer; + public KnoxSessionStore(final CryptoService cryptoService, final String clusterName, final String domainSuffix) { this(cryptoService, clusterName, domainSuffix, new HashMap()); } @@ -89,17 +90,11 @@ public KnoxSessionStore(final CryptoService cryptoService, final String clusterName, final String domainSuffix, final Map sessionStoreConfigs) { - javaSerializationHelper = new JavaSerializationHelper(); this.cryptoService = cryptoService; this.clusterName = clusterName; this.domainSuffix = domainSuffix; this.sessionStoreConfigs = sessionStoreConfigs; - } - - - @Override - public String getOrCreateSessionId(WebContext context) { - return null; + this.serializer = new JavaSerializer(); } private Serializable uncompressDecryptBase64(final String v) { @@ -113,7 +108,7 @@ private Serializable uncompressDecryptBase64(final String v) { result.salt); if (clear != null) { try { - return javaSerializationHelper.deserializeFromBytes(unCompress(clear)); + return (Serializable)serializer.deserializeFromBytes(unCompress(clear)); } catch (IOException e) { throw new TechnicalException(e); } @@ -122,9 +117,24 @@ private Serializable uncompressDecryptBase64(final String v) { return null; } + /** + * Get or create the session identifier and initialize the session with it if + * necessary. + * + * @param context the web context + * @param createSession + * @return the optional session identifier + */ + @Override + public Optional getSessionId(WebContext context, + boolean createSession) { + /* return session id from request */ + return Optional.of(""); + } + @Override public Optional get(WebContext context, String key) { - final Cookie cookie = ContextHelper.getCookie(context, PAC4J_SESSION_PREFIX + key); + final Cookie cookie = WebContextHelper.getCookie(context, PAC4J_SESSION_PREFIX + key); Object value = null; if (cookie != null) { value = uncompressDecryptBase64(cookie.getValue()); @@ -138,7 +148,7 @@ private String compressEncryptBase64(final Object o) { || (o instanceof Map && ((Map)o).isEmpty())) { return null; } else { - byte[] bytes = javaSerializationHelper.serializeToBytes((Serializable) o); + byte[] bytes = serializer.serializeToBytes(o); /* compress the data */ try { @@ -184,7 +194,7 @@ public void set(WebContext context, String key, Object value) { throw new TechnicalException(e); } cookie.setHttpOnly(true); - cookie.setSecure(ContextHelper.isHttpsOrSecure(context)); + cookie.setSecure(WebContextHelper.isHttpsOrSecure(context)); /* * set the correct path for setting pac4j profile cookie. @@ -281,7 +291,7 @@ private Object clearUserProfile(final Object value) { } @Override - public Optional> buildFromTrackableSession(WebContext arg0, Object arg1) { + public Optional buildFromTrackableSession(WebContext arg0, Object arg1) { return Optional.empty(); } diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java index e73d8feab1..837d4f1a75 100644 --- a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java +++ b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java @@ -27,6 +27,8 @@ import org.apache.knox.gateway.services.GatewayServices; import org.apache.knox.gateway.services.security.AliasService; import org.apache.knox.gateway.services.security.impl.DefaultCryptoService; +import org.easymock.Capture; +import org.easymock.CaptureType; import org.easymock.EasyMock; import org.junit.Test; import org.pac4j.core.util.Pac4jConstants; @@ -43,6 +45,8 @@ import java.util.Properties; import java.util.stream.Collectors; +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.isA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -105,12 +109,19 @@ public void test() throws Exception { request.setRequestURL(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL); request.setCookies(new Cookie[0]); request.setServerName(LOCALHOST); + + Capture captureSetCookieHeaders = EasyMock.newCapture( + CaptureType.ALL); MockHttpServletResponse response = new MockHttpServletResponse(); + response.addHeader(isA(String.class), capture(captureSetCookieHeaders)); + FilterChain filterChain = EasyMock.createNiceMock(FilterChain.class); dispatcher.doFilter(request, response, filterChain); // it should be a redirection to the idp topology assertEquals(302, response.getStatus()); assertEquals(PAC4J_CALLBACK_URL + "?" + Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER + "=true&" + Pac4jConstants.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS, response.getHeaders().get("Location")); + System.out.println("Set-headers: "+captureSetCookieHeaders.getValues().size()); + // we should have one cookie for the saved requested url List cookies = response.getCookies(); assertEquals(3, cookies.size()); diff --git a/pom.xml b/pom.xml index 910c1b119d..b60d5c310a 100644 --- a/pom.xml +++ b/pom.xml @@ -222,10 +222,9 @@ 2.3.3 2.3.2 1.2.2 - 7.5.2 3.27.0-GA 3.4.1.Final - 5.0.0 + 6.1.0 3.4 2.6 9.4.45.v20220203 @@ -249,8 +248,8 @@ 8.14.1 v12.18.2 2.7.5 - 3.4.5 - 4.5.2 + 4.2.0 + 5.4.3 42.3.3 8.0.28 3.16.1 @@ -277,6 +276,7 @@ 2.3.0 0.10 3.5.7 + 8.0.0 @@ -2198,7 +2198,7 @@ org.pac4j - pac4j-saml-opensamlv3 + pac4j-saml ${pac4j.version} @@ -2242,6 +2242,12 @@ + + org.pac4j + pac4j-jee + ${pac4j.version} + + org.opensaml