keycloak-aplcache

Details

diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
index fba8b8f..da80cef 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
@@ -178,6 +178,8 @@ public class KeycloakServletExtension implements ServletExtension {
         cookieConfig.setPath(deploymentInfo.getContextPath());
         deploymentInfo.setServletSessionConfig(cookieConfig);
 
+        ChangeSessionIdOnLogin.turnOffChangeSessionIdOnLogin(deploymentInfo);
+
         deploymentInfo.addListener(new ListenerInfo(UndertowNodesRegistrationManagementWrapper.class, new InstanceFactory<UndertowNodesRegistrationManagementWrapper>() {
 
             @Override
diff --git a/integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/ChangeSessionIdOnLogin.java b/integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/ChangeSessionIdOnLogin.java
new file mode 100755
index 0000000..1e6869a
--- /dev/null
+++ b/integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/ChangeSessionIdOnLogin.java
@@ -0,0 +1,27 @@
+package org.keycloak.adapters.undertow;
+
+import io.undertow.servlet.api.DeploymentInfo;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ChangeSessionIdOnLogin {
+    /**
+     * This is a hack to be backward compatible between Undertow 1.3+ and versions lower.  In Undertow 1.3, a new
+     * switch was added setChangeSessionIdOnLogin, this screws up session management for keycloak as after the session id
+     * is uploaded to Keycloak, undertow changes the session id and it can't be invalidated.
+     *
+     * @param deploymentInfo
+     */
+    public static void turnOffChangeSessionIdOnLogin(DeploymentInfo deploymentInfo) {
+        try {
+            Method method = DeploymentInfo.class.getMethod("setChangeSessionIdOnLogin", boolean.class);
+            method.invoke(deploymentInfo, false);
+        } catch (Exception ignore) {
+
+        }
+    }
+}
diff --git a/integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java b/integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java
new file mode 100755
index 0000000..6397c6a
--- /dev/null
+++ b/integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java
@@ -0,0 +1,63 @@
+package org.keycloak.adapters.undertow;
+import io.undertow.server.HttpServerExchange;
+import io.undertow.server.session.Session;
+import io.undertow.servlet.handlers.ServletRequestContext;
+import io.undertow.servlet.spec.HttpSessionImpl;
+
+import javax.servlet.http.HttpSession;
+import java.io.Serializable;
+import java.security.AccessController;
+
+/**
+ * Saved servlet request.
+ *
+ * Note bill burke: I had to fork this because Undertow was automatically restoring the request before the code could be
+ * processed and redirected.
+ *
+ * CachedAuthenticatedSessionHandler was restoring the request before the authentication manager could read the code from the URI
+ * Originally, I copied SavedRequest as is, but there are type mismatches between Undertow 1.1.1 and 1.3.10.
+ * So, trySaveRequest calls the same undertow version, removes the saved request, stores it in a different session attribute,
+ * then restores the old attribute later
+ *
+ *
+ * @author Stuart Douglas
+ */
+public class SavedRequest implements Serializable {
+
+    private static final String SESSION_KEY = SavedRequest.class.getName();
+
+    public static void trySaveRequest(final HttpServerExchange exchange) {
+        io.undertow.servlet.util.SavedRequest.trySaveRequest(exchange);
+        final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
+        HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
+        Session underlyingSession;
+        if(System.getSecurityManager() == null) {
+            underlyingSession = session.getSession();
+        } else {
+            underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
+        }
+        io.undertow.servlet.util.SavedRequest request = (io.undertow.servlet.util.SavedRequest) underlyingSession.removeAttribute(io.undertow.servlet.util.SavedRequest.class.getName());
+        if (request != null) underlyingSession.setAttribute(SESSION_KEY, request);
+
+
+    }
+
+    public static void tryRestoreRequest(final HttpServerExchange exchange, HttpSession session) {
+        if(session instanceof HttpSessionImpl) {
+
+            Session underlyingSession;
+            if(System.getSecurityManager() == null) {
+                underlyingSession = ((HttpSessionImpl) session).getSession();
+            } else {
+                underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
+            }
+            io.undertow.servlet.util.SavedRequest request = (io.undertow.servlet.util.SavedRequest) underlyingSession.removeAttribute(SESSION_KEY);
+            if (request != null) {
+                underlyingSession.setAttribute(io.undertow.servlet.util.SavedRequest.class.getName(), request);
+                io.undertow.servlet.util.SavedRequest.tryRestoreRequest(exchange, session);
+
+            }
+
+        }
+    }
+}
diff --git a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java
index ad22718..219597e 100755
--- a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java
+++ b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java
@@ -35,6 +35,7 @@ import org.keycloak.adapters.saml.SamlDeployment;
 import org.keycloak.adapters.saml.SamlDeploymentContext;
 import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
 import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
+import org.keycloak.adapters.undertow.ChangeSessionIdOnLogin;
 import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
 import org.keycloak.saml.common.exceptions.ParsingException;
 
@@ -183,8 +184,9 @@ public class SamlServletExtension implements ServletExtension {
         ServletSessionConfig cookieConfig = new ServletSessionConfig();
         cookieConfig.setPath(deploymentInfo.getContextPath());
         deploymentInfo.setServletSessionConfig(cookieConfig);
+        ChangeSessionIdOnLogin.turnOffChangeSessionIdOnLogin(deploymentInfo);
 
-     }
+    }
 
     protected ServletSamlAuthMech createAuthMech(DeploymentInfo deploymentInfo, SamlDeploymentContext deploymentContext, UndertowUserSessionManagement userSessionManagement) {
         return new ServletSamlAuthMech(deploymentContext, userSessionManagement, getErrorPage(deploymentInfo));
diff --git a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
index 34d718b..d9885d8 100755
--- a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
+++ b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
@@ -6,11 +6,11 @@ import io.undertow.server.HttpServerExchange;
 import io.undertow.server.session.SessionManager;
 import io.undertow.servlet.handlers.ServletRequestContext;
 import io.undertow.servlet.spec.HttpSessionImpl;
-import io.undertow.servlet.util.SavedRequest;
 import org.jboss.logging.Logger;
 import org.keycloak.adapters.spi.SessionIdMapper;
 import org.keycloak.adapters.saml.SamlSession;
 import org.keycloak.adapters.saml.SamlSessionStore;
+import org.keycloak.adapters.undertow.SavedRequest;
 import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
 import org.keycloak.common.util.KeycloakUriBuilder;
 import org.keycloak.dom.saml.v2.protocol.StatusType;