keycloak-uncached
Changes
integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java 2(+2 -0)
integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/ChangeSessionIdOnLogin.java 27(+27 -0)
integration/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/SavedRequest.java 63(+63 -0)
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;