keycloak-aplcache

KEYCLOAK-2377

1/22/2016 8:00:51 PM

Changes

Details

diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java
index 47eb58e..fd676f5 100755
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java
@@ -433,6 +433,16 @@ public class AdapterDeploymentContext {
         public void setPrincipalAttribute(String principalAttribute) {
             delegate.setPrincipalAttribute(principalAttribute);
         }
+
+        @Override
+        public boolean isTurnOffChangeSessionIdOnLogin() {
+            return delegate.isTurnOffChangeSessionIdOnLogin();
+        }
+
+        @Override
+        public void setTurnOffChangeSessionIdOnLogin(boolean turnOffChangeSessionIdOnLogin) {
+            delegate.setTurnOffChangeSessionIdOnLogin(turnOffChangeSessionIdOnLogin);
+        }
     }
 
     protected KeycloakUriBuilder getBaseBuilder(HttpFacade facade, String base) {
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
index 5edaa81..b97ecdb 100755
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java
@@ -57,6 +57,8 @@ public class KeycloakDeployment {
     protected boolean alwaysRefreshToken;
     protected boolean registerNodeAtStartup;
     protected int registerNodePeriod;
+    protected boolean turnOffChangeSessionIdOnLogin;
+
     protected volatile int notBefore;
 
     public KeycloakDeployment() {
@@ -361,4 +363,12 @@ public class KeycloakDeployment {
     public void setPrincipalAttribute(String principalAttribute) {
         this.principalAttribute = principalAttribute;
     }
+
+    public boolean isTurnOffChangeSessionIdOnLogin() {
+        return turnOffChangeSessionIdOnLogin;
+    }
+
+    public void setTurnOffChangeSessionIdOnLogin(boolean turnOffChangeSessionIdOnLogin) {
+        this.turnOffChangeSessionIdOnLogin = turnOffChangeSessionIdOnLogin;
+    }
 }
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java
index 14cf9ab..0bda9b2 100755
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java
@@ -88,6 +88,9 @@ public class KeycloakDeploymentBuilder {
             throw new RuntimeException("You must specify auth-url");
         }
         deployment.setAuthServerBaseUrl(adapterConfig);
+        if (adapterConfig.getTurnOffChangeSessionIdOnLogin() != null) {
+            deployment.setTurnOffChangeSessionIdOnLogin(adapterConfig.getTurnOffChangeSessionIdOnLogin());
+        }
 
         log.debug("Use authServerUrl: " + deployment.getAuthServerBaseUrl() + ", tokenUrl: " + deployment.getTokenUrl() + ", relativeUrls: " + deployment.getRelativeUrls());
         return deployment;
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
index cc6b188..e69e6f2 100755
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
@@ -293,7 +293,7 @@ public class OAuthRequestAuthenticator {
         strippedOauthParametersRequestUri = stripOauthParametersFromRedirect();
         try {
             // For COOKIE store we don't have httpSessionId and single sign-out won't be available
-            String httpSessionId = deployment.getTokenStore() == TokenStore.SESSION ? reqAuthenticator.getHttpSessionId(true) : null;
+            String httpSessionId = deployment.getTokenStore() == TokenStore.SESSION ? reqAuthenticator.changeHttpSessionId(true) : null;
             tokenResponse = ServerRequest.invokeAccessCodeToToken(deployment, code, strippedOauthParametersRequestUri, httpSessionId);
         } catch (ServerRequest.HttpFailure failure) {
             log.error("failed to turn code into token");
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java
index 6b4d9f0..8f695b0 100755
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java
@@ -141,7 +141,13 @@ public abstract class RequestAuthenticator {
 
     protected abstract void completeOAuthAuthentication(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal);
     protected abstract void completeBearerAuthentication(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal, String method);
-    protected abstract String getHttpSessionId(boolean create);
+
+    /**
+     * After code is received, we change the session id if possible to guard against https://www.owasp.org/index.php/Session_Fixation
+     * @param create
+     * @return
+     */
+    protected abstract String changeHttpSessionId(boolean create);
 
     protected void completeAuthentication(BearerTokenRequestAuthenticator bearer, String method) {
         RefreshableKeycloakSecurityContext session = new RefreshableKeycloakSecurityContext(deployment, null, bearer.getTokenString(), bearer.getToken(), null, null, null);
diff --git a/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd b/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd
index 75de38a..89b37b6 100755
--- a/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd
+++ b/adapters/oidc/as7-eap6/as7-subsystem/src/main/resources/schema/keycloak_1_1.xsd
@@ -87,6 +87,7 @@
             <xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
         </xs:all>
         <xs:attribute name="name" type="xs:string" use="required">
             <xs:annotation>
diff --git a/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/Jetty91RequestAuthenticator.java b/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/Jetty91RequestAuthenticator.java
new file mode 100755
index 0000000..cc3395f
--- /dev/null
+++ b/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/Jetty91RequestAuthenticator.java
@@ -0,0 +1,30 @@
+package org.keycloak.adapters.jetty;
+
+import org.eclipse.jetty.server.Request;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.jetty.core.JettyRequestAuthenticator;
+import org.keycloak.adapters.spi.HttpFacade;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Jetty91RequestAuthenticator extends JettyRequestAuthenticator {
+    public Jetty91RequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort, Request request) {
+        super(facade, deployment, tokenStore, sslRedirectPort, request);
+    }
+
+    @Override
+    protected String changeHttpSessionId(boolean create) {
+        Request request = this.request;
+        HttpSession session = request.getSession(false);
+        if (session == null) {
+            return request.getSession(true).getId();
+        }
+        if (deployment.isTurnOffChangeSessionIdOnLogin() == false) return request.changeSessionId();
+        else return session.getId();
+    }
+}
diff --git a/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java b/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
index a319266..5c7570f 100755
--- a/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
+++ b/adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
@@ -7,7 +7,9 @@ import org.eclipse.jetty.server.UserIdentity;
 import org.keycloak.adapters.AdapterTokenStore;
 import org.keycloak.adapters.KeycloakDeployment;
 import org.keycloak.adapters.jetty.core.AbstractKeycloakJettyAuthenticator;
+import org.keycloak.adapters.jetty.core.JettyRequestAuthenticator;
 import org.keycloak.adapters.jetty.core.JettySessionTokenStore;
+import org.keycloak.adapters.jetty.spi.JettyHttpFacade;
 
 import javax.servlet.ServletRequest;
 
@@ -42,5 +44,12 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
         };
     }
 
+    @Override
+    protected JettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade,
+                                                                   KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
+        return new Jetty91RequestAuthenticator(facade, deployment, tokenStore, -1, request);
+    }
+
+
 
 }
diff --git a/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/Jetty92RequestAuthenticator.java b/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/Jetty92RequestAuthenticator.java
new file mode 100755
index 0000000..9c7e127
--- /dev/null
+++ b/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/Jetty92RequestAuthenticator.java
@@ -0,0 +1,30 @@
+package org.keycloak.adapters.jetty;
+
+import org.eclipse.jetty.server.Request;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.jetty.core.JettyRequestAuthenticator;
+import org.keycloak.adapters.spi.HttpFacade;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Jetty92RequestAuthenticator extends JettyRequestAuthenticator {
+    public Jetty92RequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort, Request request) {
+        super(facade, deployment, tokenStore, sslRedirectPort, request);
+    }
+
+    @Override
+    protected String changeHttpSessionId(boolean create) {
+        Request request = this.request;
+        HttpSession session = request.getSession(false);
+        if (session == null) {
+            return request.getSession(true).getId();
+        }
+        if (deployment.isTurnOffChangeSessionIdOnLogin() == false) return request.changeSessionId();
+        else return session.getId();
+    }
+}
diff --git a/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java b/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
index 2aec5ef..67841c1 100755
--- a/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
+++ b/adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java
@@ -7,7 +7,9 @@ import org.eclipse.jetty.server.UserIdentity;
 import org.keycloak.adapters.AdapterTokenStore;
 import org.keycloak.adapters.KeycloakDeployment;
 import org.keycloak.adapters.jetty.core.AbstractKeycloakJettyAuthenticator;
+import org.keycloak.adapters.jetty.core.JettyRequestAuthenticator;
 import org.keycloak.adapters.jetty.core.JettySessionTokenStore;
+import org.keycloak.adapters.jetty.spi.JettyHttpFacade;
 
 import javax.servlet.ServletRequest;
 
@@ -41,4 +43,11 @@ public class KeycloakJettyAuthenticator extends AbstractKeycloakJettyAuthenticat
     public AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment) {
         return new JettySessionTokenStore(request, resolvedDeployment, new JettyAdapterSessionStore(request));
     }
+
+    @Override
+    protected JettyRequestAuthenticator createRequestAuthenticator(Request request, JettyHttpFacade facade,
+                                                                   KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
+        return new Jetty92RequestAuthenticator(facade, deployment, tokenStore, -1, request);
+    }
+
 }
diff --git a/adapters/oidc/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java b/adapters/oidc/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java
index 2d0d2a2..d9e9a39 100755
--- a/adapters/oidc/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java
+++ b/adapters/oidc/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java
@@ -76,7 +76,7 @@ public class JettyRequestAuthenticator extends RequestAuthenticator {
 
 
     @Override
-    protected String getHttpSessionId(boolean create) {
+    protected String changeHttpSessionId(boolean create) {
         HttpSession session = request.getSession(create);
         return session != null ? session.getId() : null;
     }
diff --git a/adapters/oidc/jetty/pom.xml b/adapters/oidc/jetty/pom.xml
index 86edf07..f1cd46b 100755
--- a/adapters/oidc/jetty/pom.xml
+++ b/adapters/oidc/jetty/pom.xml
@@ -14,7 +14,6 @@
     <packaging>pom</packaging>
 
     <modules>
-        <module>jetty-adapter-spi</module>
         <module>jetty-core</module>
         <module>jetty8.1</module>
         <module>jetty9.2</module>
diff --git a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/FilterRequestAuthenticator.java b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/FilterRequestAuthenticator.java
index 70cb7e9..4067266 100755
--- a/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/FilterRequestAuthenticator.java
+++ b/adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/FilterRequestAuthenticator.java
@@ -78,7 +78,7 @@ public class FilterRequestAuthenticator extends RequestAuthenticator {
     }
 
     @Override
-    protected String getHttpSessionId(boolean create) {
+    protected String changeHttpSessionId(boolean create) {
         HttpSession session = request.getSession(create);
         return session != null ? session.getId() : null;
     }
diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java
index 5e1ed05..fada455 100755
--- a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java
+++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java
@@ -82,7 +82,7 @@ public class SpringSecurityRequestAuthenticator extends RequestAuthenticator {
     }
 
     @Override
-    protected String getHttpSessionId(boolean create) {
+    protected String changeHttpSessionId(boolean create) {
         HttpSession session = request.getSession(create);
         return session != null ? session.getId() : null;
     }
diff --git a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java
index c44610d..89202fb 100755
--- a/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java
+++ b/adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java
@@ -95,13 +95,13 @@ public class SpringSecurityRequestAuthenticatorTest {
 
     @Test
     public void testGetHttpSessionIdTrue() throws Exception {
-        String sessionId = authenticator.getHttpSessionId(true);
+        String sessionId = authenticator.changeHttpSessionId(true);
         assertNotNull(sessionId);
     }
 
     @Test
     public void testGetHttpSessionIdFalse() throws Exception {
-        String sessionId = authenticator.getHttpSessionId(false);
+        String sessionId = authenticator.changeHttpSessionId(false);
         assertNull(sessionId);
     }
 }
diff --git a/adapters/oidc/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java b/adapters/oidc/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
index 2e30429..e1426dc 100755
--- a/adapters/oidc/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
+++ b/adapters/oidc/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
@@ -6,6 +6,8 @@ import org.apache.catalina.connector.Response;
 import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.deploy.LoginConfig;
 import org.apache.catalina.realm.GenericPrincipal;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
@@ -55,4 +57,5 @@ public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorVal
             }
         };
     }
+
 }
diff --git a/adapters/oidc/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java b/adapters/oidc/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
index fa94c34..4dc19dd 100755
--- a/adapters/oidc/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
+++ b/adapters/oidc/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
@@ -5,6 +5,8 @@ import org.apache.catalina.connector.Response;
 import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.deploy.LoginConfig;
 import org.apache.catalina.realm.GenericPrincipal;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
@@ -51,4 +53,5 @@ public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorVal
             }
         };
     }
+
 }
diff --git a/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java b/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
index eea4f03..bd8cee6 100755
--- a/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
+++ b/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java
@@ -7,6 +7,9 @@ import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.descriptor.web.LoginConfig;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.spi.HttpFacade;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
@@ -71,4 +74,9 @@ public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorVal
             }
         };
     }
+
+    @Override
+    protected AdapterTokenStore getTokenStore(Request request, HttpFacade facade, KeycloakDeployment resolvedDeployment) {
+        return super.getTokenStore(request, facade, resolvedDeployment);
+    }
 }
diff --git a/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/Tomcat8RequestAuthenticator.java b/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/Tomcat8RequestAuthenticator.java
new file mode 100755
index 0000000..b221129
--- /dev/null
+++ b/adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/Tomcat8RequestAuthenticator.java
@@ -0,0 +1,28 @@
+package org.keycloak.adapters.tomcat;
+
+import org.apache.catalina.connector.Request;
+import org.keycloak.adapters.AdapterTokenStore;
+import org.keycloak.adapters.KeycloakDeployment;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Tomcat8RequestAuthenticator extends CatalinaRequestAuthenticator {
+    public Tomcat8RequestAuthenticator(KeycloakDeployment deployment, AdapterTokenStore tokenStore, CatalinaHttpFacade facade, Request request, GenericPrincipalFactory principalFactory) {
+        super(deployment, tokenStore, facade, request, principalFactory);
+    }
+
+    @Override
+    protected String changeHttpSessionId(boolean create) {
+        Request request = this.request;
+        HttpSession session = request.getSession(false);
+        if (session == null) {
+            return request.getSession(true).getId();
+        }
+        if (deployment.isTurnOffChangeSessionIdOnLogin() == false) return request.changeSessionId();
+        else return session.getId();
+    }
+}
diff --git a/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java b/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java
index 20c87bd..99ad2a7 100755
--- a/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java
+++ b/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java
@@ -185,7 +185,7 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat
 
         nodesRegistrationManagement.tryRegister(deployment);
 
-        CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, tokenStore, facade, request, createPrincipalFactory());
+        CatalinaRequestAuthenticator authenticator = createRequestAuthenticator(request, facade, deployment, tokenStore);
         AuthOutcome outcome = authenticator.authenticate();
         if (outcome == AuthOutcome.AUTHENTICATED) {
             if (facade.isEnded()) {
@@ -200,6 +200,10 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat
         return false;
     }
 
+    protected CatalinaRequestAuthenticator createRequestAuthenticator(Request request, CatalinaHttpFacade facade, KeycloakDeployment deployment, AdapterTokenStore tokenStore) {
+        return new CatalinaRequestAuthenticator(deployment, tokenStore, facade, request, createPrincipalFactory());
+    }
+
     /**
      * Checks that access token is still valid.  Will attempt refresh of token if it is not.
      *
@@ -230,7 +234,7 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat
         }
 
         if (resolvedDeployment.getTokenStore() == TokenStore.SESSION) {
-            store = new CatalinaSessionTokenStore(request, resolvedDeployment, userSessionManagement, createPrincipalFactory(), this);
+            store = createSessionTokenStore(request, resolvedDeployment);
         } else {
             store = new CatalinaCookieTokenStore(request, facade, resolvedDeployment, createPrincipalFactory());
         }
@@ -239,4 +243,10 @@ public abstract class AbstractKeycloakAuthenticatorValve extends FormAuthenticat
         return store;
     }
 
+    private AdapterTokenStore createSessionTokenStore(Request request, KeycloakDeployment resolvedDeployment) {
+        AdapterTokenStore store;
+        store = new CatalinaSessionTokenStore(request, resolvedDeployment, userSessionManagement, createPrincipalFactory(), this);
+        return store;
+    }
+
 }
diff --git a/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java b/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java
index 0883c76..6c88620 100755
--- a/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java
+++ b/adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java
@@ -83,7 +83,7 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator {
     }
 
     @Override
-    protected String getHttpSessionId(boolean create) {
+    protected String changeHttpSessionId(boolean create) {
         HttpSession session = request.getSession(create);
         return session != null ? session.getId() : null;
     }
diff --git a/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java b/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
index 18c846c..ca938bb 100755
--- a/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
+++ b/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java
@@ -72,7 +72,7 @@ public abstract class AbstractUndertowRequestAuthenticator extends RequestAuthen
     }
 
     @Override
-    protected String getHttpSessionId(boolean create) {
+    protected String changeHttpSessionId(boolean create) {
         if (create) {
             Session session = Sessions.getOrCreateSession(exchange);
             return session.getId();
diff --git a/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java b/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
index 8696a04..39b4fa7 100755
--- a/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
+++ b/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java
@@ -177,7 +177,7 @@ public class KeycloakServletExtension implements ServletExtension {
         ServletSessionConfig cookieConfig = new ServletSessionConfig();
         cookieConfig.setPath(deploymentInfo.getContextPath());
         deploymentInfo.setServletSessionConfig(cookieConfig);
-        ChangeSessionIdOnLogin.turnOffChangeSessionIdOnLogin(deploymentInfo);
+        ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
         deploymentInfo.addListener(new ListenerInfo(UndertowNodesRegistrationManagementWrapper.class, new InstanceFactory<UndertowNodesRegistrationManagementWrapper>() {
 
             @Override
diff --git a/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java b/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java
index 881407d..2c288ac 100755
--- a/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java
+++ b/adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java
@@ -63,6 +63,11 @@ public class ServletRequestAuthenticator extends AbstractUndertowRequestAuthenti
     }
 
     @Override
+    protected String changeHttpSessionId(boolean create) {
+        if (deployment.isTurnOffChangeSessionIdOnLogin() == false) return ChangeSessionId.changeSessionId(exchange, create);
+        else return getHttpSessionId(create);
+    }
+
     protected String getHttpSessionId(boolean create) {
         HttpSession session = getSession(create);
         return session != null ? session.getId() : null;
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java
index d16a25e..0098a78 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java
@@ -77,6 +77,12 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
                     .setAllowExpression(true)
                     .setDefaultValue(new ModelNode(false))
                     .build();
+    protected static final SimpleAttributeDefinition TURN_OFF_CHANGE_SESSION =
+            new SimpleAttributeDefinitionBuilder("turn-off-change-session-id-on-login", ModelType.BOOLEAN, true)
+                    .setXmlName("turn-off-change-session-id-on-login")
+                    .setAllowExpression(true)
+                    .setDefaultValue(new ModelNode(false))
+                    .build();
 
     protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
     static {
@@ -86,6 +92,7 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
         DEPLOYMENT_ONLY_ATTRIBUTES.add(BEARER_ONLY);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(ENABLE_BASIC_AUTH);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_CLIENT);
+        DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
     }
 
     protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties
index c00bd8d..047e3ff 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties
@@ -63,6 +63,7 @@ keycloak.secure-deployment.register-node-at-startup=Cluster setting
 keycloak.secure-deployment.register-node-period=how often to re-register node
 keycloak.secure-deployment.token-store=cookie or session storage for auth session data
 keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
+keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login.  Change this to true if you want to turn this off
 
 keycloak.secure-deployment.credential=Credential value
 
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
index 75de38a..89b37b6 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
@@ -87,6 +87,7 @@
             <xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
         </xs:all>
         <xs:attribute name="name" type="xs:string" use="required">
             <xs:annotation>
diff --git a/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml b/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml
old mode 100644
new mode 100755
index e512f0e..e4e097d
--- a/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml
+++ b/adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml
@@ -3,6 +3,7 @@
         <realm>master</realm>
         <resource>web-console</resource>
         <use-resource-role-mappings>true</use-resource-role-mappings>
+        <turn-off-change-session-id-on-login>false</turn-off-change-session-id-on-login>
         <realm-public-key>
             MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
         </realm-public-key>
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
index 1932cc8..a09c3b8 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java
@@ -77,6 +77,12 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
                     .setAllowExpression(true)
                     .setDefaultValue(new ModelNode(false))
                     .build();
+    protected static final SimpleAttributeDefinition TURN_OFF_CHANGE_SESSION =
+            new SimpleAttributeDefinitionBuilder("turn-off-change-session-id-on-login", ModelType.BOOLEAN, true)
+                    .setXmlName("turn-off-change-session-id-on-login")
+                    .setAllowExpression(true)
+                    .setDefaultValue(new ModelNode(false))
+                    .build();
 
     protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
     static {
@@ -86,6 +92,7 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
         DEPLOYMENT_ONLY_ATTRIBUTES.add(BEARER_ONLY);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(ENABLE_BASIC_AUTH);
         DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_CLIENT);
+        DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
     }
 
     protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
index c00bd8d..047e3ff 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties
@@ -63,6 +63,7 @@ keycloak.secure-deployment.register-node-at-startup=Cluster setting
 keycloak.secure-deployment.register-node-period=how often to re-register node
 keycloak.secure-deployment.token-store=cookie or session storage for auth session data
 keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
+keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login.  Change this to true if you want to turn this off
 
 keycloak.secure-deployment.credential=Credential value
 
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
index 0abaac1..c6298f8 100755
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak_1_1.xsd
@@ -87,6 +87,7 @@
             <xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
         </xs:all>
         <xs:attribute name="name" type="xs:string" use="required">
             <xs:annotation>
diff --git a/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml b/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
old mode 100644
new mode 100755
index e512f0e..e4e097d
--- a/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
+++ b/adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml
@@ -3,6 +3,7 @@
         <realm>master</realm>
         <resource>web-console</resource>
         <use-resource-role-mappings>true</use-resource-role-mappings>
+        <turn-off-change-session-id-on-login>false</turn-off-change-session-id-on-login>
         <realm-public-key>
             MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
         </realm-public-key>
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java
index 91a016c..87069c3 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java
@@ -12,6 +12,7 @@ public class ConfigXmlConstants {
     public static final String NAME_ID_POLICY_FORMAT_ATTR = "nameIDPolicyFormat";
     public static final String FORCE_AUTHENTICATION_ATTR = "forceAuthentication";
     public static final String IS_PASSIVE_ATTR = "isPassive";
+    public static final String TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN_ATTR = "turnOffChangeSessionIdOnLogin";
     public static final String SIGNATURE_ALGORITHM_ATTR = "signatureAlgorithm";
     public static final String SIGNATURE_CANONICALIZATION_METHOD_ATTR = "signatureCanonicalizationMethod";
     public static final String LOGOUT_PAGE_ATTR = "logoutPage";
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java
index 14b04e1..7d6d57a 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java
@@ -66,6 +66,7 @@ public class SPXmlParser extends AbstractParser {
         sp.setNameIDPolicyFormat(getAttributeValue(startElement, ConfigXmlConstants.NAME_ID_POLICY_FORMAT_ATTR));
         sp.setForceAuthentication(getBooleanAttributeValue(startElement, ConfigXmlConstants.FORCE_AUTHENTICATION_ATTR));
         sp.setIsPassive(getBooleanAttributeValue(startElement, ConfigXmlConstants.IS_PASSIVE_ATTR));
+        sp.setTurnOffChangeSessionIdOnLogin(getBooleanAttributeValue(startElement, ConfigXmlConstants.TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN_ATTR));
         while (xmlEventReader.hasNext()) {
             XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
             if (xmlEvent == null)
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/SP.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/SP.java
index 5203b13..17c8343 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/SP.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/SP.java
@@ -34,6 +34,7 @@ public class SP implements Serializable {
     private String sslPolicy;
     private boolean forceAuthentication;
     private boolean isPassive;
+    private boolean turnOffChangeSessionIdOnLogin;
     private String logoutPage;
     private List<Key> keys;
     private String nameIDPolicyFormat;
@@ -73,6 +74,14 @@ public class SP implements Serializable {
         this.isPassive = isPassive;
     }
 
+    public boolean isTurnOffChangeSessionIdOnLogin() {
+        return turnOffChangeSessionIdOnLogin;
+    }
+
+    public void setTurnOffChangeSessionIdOnLogin(boolean turnOffChangeSessionIdOnLogin) {
+        this.turnOffChangeSessionIdOnLogin = turnOffChangeSessionIdOnLogin;
+    }
+
     public List<Key> getKeys() {
         return keys;
     }
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java
index 7aab095..2c925e0 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java
@@ -201,6 +201,7 @@ public class DefaultSamlDeployment implements SamlDeployment {
     private String nameIDPolicyFormat;
     private boolean forceAuthentication;
     private boolean isPassive;
+    private boolean turnOffChangeSessionIdOnLogin;
     private PrivateKey decryptionKey;
     private KeyPair signingKeyPair;
     private String assertionConsumerServiceUrl;
@@ -212,6 +213,16 @@ public class DefaultSamlDeployment implements SamlDeployment {
     private String signatureCanonicalizationMethod;
 
     @Override
+    public boolean turnOffChangeSessionIdOnLogin() {
+        return turnOffChangeSessionIdOnLogin;
+    }
+
+    public void setTurnOffChangeSessionIdOnLogin(boolean turnOffChangeSessionIdOnLogin) {
+        this.turnOffChangeSessionIdOnLogin = turnOffChangeSessionIdOnLogin;
+    }
+
+
+    @Override
     public IDP getIDP() {
         return idp;
     }
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java
index 8c53236..14ce5a3 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java
@@ -57,6 +57,7 @@ public interface SamlDeployment {
     String getNameIDPolicyFormat();
     boolean isForceAuthentication();
     boolean isIsPassive();
+    boolean turnOffChangeSessionIdOnLogin();
     PrivateKey getDecryptionKey();
     KeyPair getSigningKeyPair();
     String getSignatureCanonicalizationMethod();
diff --git a/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd b/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
index d3e55f9..1f8b26b 100755
--- a/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
+++ b/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
@@ -34,6 +34,7 @@
         <xs:attribute name="logoutPage" type="xs:string" use="optional"/>
         <xs:attribute name="forceAuthentication" type="xs:boolean" use="optional"/>
         <xs:attribute name="isPassive" type="xs:boolean" use="optional"/>
+        <xs:attribute name="turnOffChangeSessionIdOnLogin" type="xs:boolean" use="optional"/>
     </xs:complexType>
 
     <xs:complexType name="keys-type">
diff --git a/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java b/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java
new file mode 100755
index 0000000..56a26ca
--- /dev/null
+++ b/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java
@@ -0,0 +1,27 @@
+package org.keycloak.adapters.saml.jetty;
+
+import org.eclipse.jetty.server.Request;
+import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
+import org.keycloak.adapters.saml.SamlDeployment;
+import org.keycloak.adapters.spi.AdapterSessionStore;
+import org.keycloak.adapters.spi.HttpFacade;
+import org.keycloak.adapters.spi.SessionIdMapper;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Jetty9SamlSessionStore extends JettySamlSessionStore {
+    public Jetty9SamlSessionStore(Request request, AdapterSessionStore sessionStore, HttpFacade facade, SessionIdMapper idMapper, JettyUserSessionManagement sessionManagement, SamlDeployment deployment) {
+        super(request, sessionStore, facade, idMapper, sessionManagement, deployment);
+    }
+
+    @Override
+    protected String changeSessionId(HttpSession session) {
+        Request request = this.request;
+        if (deployment.turnOffChangeSessionIdOnLogin() == false) return request.changeSessionId();
+        else return session.getId();
+    }
+}
diff --git a/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java b/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java
index f5fdf7d..238c84b 100755
--- a/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java
+++ b/adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java
@@ -4,8 +4,10 @@ import org.eclipse.jetty.server.Authentication;
 import org.eclipse.jetty.server.HttpChannel;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.UserIdentity;
+import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
 import org.keycloak.adapters.spi.AdapterSessionStore;
 import org.keycloak.adapters.saml.SamlDeployment;
+import org.keycloak.adapters.spi.HttpFacade;
 
 import javax.servlet.ServletRequest;
 
@@ -40,5 +42,13 @@ public class KeycloakSamlAuthenticator extends AbstractSamlAuthenticator {
         };
     }
 
+    @Override
+    protected JettySamlSessionStore createJettySamlSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+        JettySamlSessionStore store;
+        store = new Jetty9SamlSessionStore(request, createSessionTokenStore(request, resolvedDeployment), facade, idMapper, new JettyUserSessionManagement(request.getSessionManager()), resolvedDeployment);
+        return store;
+    }
+
+
 
 }
diff --git a/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java b/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java
new file mode 100755
index 0000000..56a26ca
--- /dev/null
+++ b/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java
@@ -0,0 +1,27 @@
+package org.keycloak.adapters.saml.jetty;
+
+import org.eclipse.jetty.server.Request;
+import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
+import org.keycloak.adapters.saml.SamlDeployment;
+import org.keycloak.adapters.spi.AdapterSessionStore;
+import org.keycloak.adapters.spi.HttpFacade;
+import org.keycloak.adapters.spi.SessionIdMapper;
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Jetty9SamlSessionStore extends JettySamlSessionStore {
+    public Jetty9SamlSessionStore(Request request, AdapterSessionStore sessionStore, HttpFacade facade, SessionIdMapper idMapper, JettyUserSessionManagement sessionManagement, SamlDeployment deployment) {
+        super(request, sessionStore, facade, idMapper, sessionManagement, deployment);
+    }
+
+    @Override
+    protected String changeSessionId(HttpSession session) {
+        Request request = this.request;
+        if (deployment.turnOffChangeSessionIdOnLogin() == false) return request.changeSessionId();
+        else return session.getId();
+    }
+}
diff --git a/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java b/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java
index 03ea508..fa802ba 100755
--- a/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java
+++ b/adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java
@@ -4,8 +4,10 @@ import org.eclipse.jetty.server.Authentication;
 import org.eclipse.jetty.server.HttpChannel;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.UserIdentity;
+import org.keycloak.adapters.jetty.spi.JettyUserSessionManagement;
 import org.keycloak.adapters.spi.AdapterSessionStore;
 import org.keycloak.adapters.saml.SamlDeployment;
+import org.keycloak.adapters.spi.HttpFacade;
 
 import javax.servlet.ServletRequest;
 
@@ -39,4 +41,11 @@ public class KeycloakSamlAuthenticator extends AbstractSamlAuthenticator {
     public AdapterSessionStore createSessionTokenStore(Request request, SamlDeployment resolvedDeployment) {
         return new JettyAdapterSessionStore(request);
     }
+
+    @Override
+    protected JettySamlSessionStore createJettySamlSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+        JettySamlSessionStore store;
+        store = new Jetty9SamlSessionStore(request, createSessionTokenStore(request, resolvedDeployment), facade, idMapper, new JettyUserSessionManagement(request.getSessionManager()), resolvedDeployment);
+        return store;
+    }
 }
diff --git a/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java b/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java
index 2df0fad..5028542 100755
--- a/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java
+++ b/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java
@@ -75,12 +75,18 @@ public abstract class AbstractSamlAuthenticator extends LoginAuthenticator {
         if (store != null) {
             return store;
         }
-        store = new JettySamlSessionStore(request, createSessionTokenStore(request, resolvedDeployment), facade, idMapper, new JettyUserSessionManagement(request.getSessionManager()));
+        store = createJettySamlSessionStore(request, facade, resolvedDeployment);
 
         request.setAttribute(TOKEN_STORE_NOTE, store);
         return store;
     }
 
+    protected JettySamlSessionStore createJettySamlSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+        JettySamlSessionStore store;
+        store = new JettySamlSessionStore(request, createSessionTokenStore(request, resolvedDeployment), facade, idMapper, new JettyUserSessionManagement(request.getSessionManager()), resolvedDeployment);
+        return store;
+    }
+
     public abstract AdapterSessionStore createSessionTokenStore(Request request, SamlDeployment resolvedDeployment);
 
     public void logoutCurrent(Request request) {
diff --git a/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java b/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java
index 6e51f11..380066e 100755
--- a/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java
+++ b/adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java
@@ -2,6 +2,7 @@ package org.keycloak.adapters.saml.jetty;
 
 import org.eclipse.jetty.server.Request;
 import org.jboss.logging.Logger;
+import org.keycloak.adapters.saml.SamlDeployment;
 import org.keycloak.adapters.spi.AdapterSessionStore;
 import org.keycloak.adapters.spi.HttpFacade;
 import org.keycloak.adapters.spi.SessionIdMapper;
@@ -23,19 +24,21 @@ import java.util.Set;
 public class JettySamlSessionStore implements SamlSessionStore {
     public static final String SAML_REDIRECT_URI = "SAML_REDIRECT_URI";
     private static final Logger log = Logger.getLogger(JettySamlSessionStore.class);
-    private Request request;
+    protected Request request;
     protected AdapterSessionStore sessionStore;
     protected HttpFacade facade;
     protected SessionIdMapper idMapper;
     protected JettyUserSessionManagement sessionManagement;
+    protected final SamlDeployment deployment;
 
     public JettySamlSessionStore(Request request, AdapterSessionStore sessionStore, HttpFacade facade,
-                                 SessionIdMapper idMapper, JettyUserSessionManagement sessionManagement) {
+                                 SessionIdMapper idMapper, JettyUserSessionManagement sessionManagement, SamlDeployment deployment) {
         this.request = request;
         this.sessionStore = sessionStore;
         this.facade = facade;
         this.idMapper = idMapper;
         this.sessionManagement = sessionManagement;
+        this.deployment = deployment;
     }
 
     @Override
@@ -132,10 +135,14 @@ public class JettySamlSessionStore implements SamlSessionStore {
         HttpSession session = request.getSession(true);
         session.setAttribute(SamlSession.class.getName(), account);
 
-        idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), session.getId());
+        idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), changeSessionId(session));
 
     }
 
+    protected String changeSessionId(HttpSession session) {
+        return session.getId();
+    }
+
     @Override
     public SamlSession getAccount() {
         HttpSession session = request.getSession(true);
diff --git a/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java b/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
index ead126a..7be5b69 100755
--- a/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
+++ b/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java
@@ -6,6 +6,10 @@ import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.tomcat.util.descriptor.web.LoginConfig;
 import org.keycloak.adapters.saml.AbstractSamlAuthenticatorValve;
+import org.keycloak.adapters.saml.CatalinaSamlSessionStore;
+import org.keycloak.adapters.saml.SamlDeployment;
+import org.keycloak.adapters.saml.SamlSessionStore;
+import org.keycloak.adapters.spi.HttpFacade;
 import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
 
 import javax.servlet.http.HttpServletResponse;
@@ -68,4 +72,12 @@ public class SamlAuthenticatorValve extends AbstractSamlAuthenticatorValve {
             }
         };
     }
+
+    @Override
+    protected SamlSessionStore createSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+        SamlSessionStore store;
+        store = new Tomcat8SamlSessionStore(userSessionManagement, createPrincipalFactory(), mapper, request, this, facade, resolvedDeployment);
+        return store;
+    }
+
 }
diff --git a/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/Tomcat8SamlSessionStore.java b/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/Tomcat8SamlSessionStore.java
new file mode 100755
index 0000000..4bd9cfa
--- /dev/null
+++ b/adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/Tomcat8SamlSessionStore.java
@@ -0,0 +1,28 @@
+package org.keycloak.adapters.saml.tomcat;
+
+import org.apache.catalina.Session;
+import org.apache.catalina.connector.Request;
+import org.keycloak.adapters.saml.AbstractSamlAuthenticatorValve;
+import org.keycloak.adapters.saml.CatalinaSamlSessionStore;
+import org.keycloak.adapters.saml.SamlDeployment;
+import org.keycloak.adapters.spi.HttpFacade;
+import org.keycloak.adapters.spi.SessionIdMapper;
+import org.keycloak.adapters.tomcat.CatalinaUserSessionManagement;
+import org.keycloak.adapters.tomcat.GenericPrincipalFactory;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class Tomcat8SamlSessionStore extends CatalinaSamlSessionStore {
+    public Tomcat8SamlSessionStore(CatalinaUserSessionManagement sessionManagement, GenericPrincipalFactory principalFactory, SessionIdMapper idMapper, Request request, AbstractSamlAuthenticatorValve valve, HttpFacade facade, SamlDeployment deployment) {
+        super(sessionManagement, principalFactory, idMapper, request, valve, facade, deployment);
+    }
+
+    @Override
+    protected String changeSessionId(Session session) {
+        Request request = this.request;
+        if (deployment.turnOffChangeSessionIdOnLogin() == false) return request.changeSessionId();
+        else return session.getId();
+    }
+}
diff --git a/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java b/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
index 3119ba7..3ec5a8f 100755
--- a/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
+++ b/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java
@@ -61,7 +61,7 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
     protected void logoutInternal(Request request) {
         CatalinaHttpFacade facade = new CatalinaHttpFacade(null, request);
         SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
-        SamlSessionStore tokenStore = getTokenStore(request, facade, deployment);
+        SamlSessionStore tokenStore = getSessionStore(request, facade, deployment);
         tokenStore.logoutAccount();
         request.setUserPrincipal(null);
     }
@@ -184,7 +184,7 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
             log.fine("deployment not configured");
             return false;
         }
-        SamlSessionStore tokenStore = getTokenStore(request, facade, deployment);
+        SamlSessionStore tokenStore = getSessionStore(request, facade, deployment);
 
 
         CatalinaSamlAuthenticator authenticator = new CatalinaSamlAuthenticator(facade, deployment, tokenStore);
@@ -229,16 +229,22 @@ public abstract class AbstractSamlAuthenticatorValve extends FormAuthenticator i
         }
     }
 
-    protected SamlSessionStore getTokenStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+    protected SamlSessionStore getSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
         SamlSessionStore store = (SamlSessionStore)request.getNote(TOKEN_STORE_NOTE);
         if (store != null) {
             return store;
         }
 
-        store = new CatalinaSamlSessionStore(userSessionManagement, createPrincipalFactory(), mapper, request, this, facade);
+        store = createSessionStore(request, facade, resolvedDeployment);
 
         request.setNote(TOKEN_STORE_NOTE, store);
         return store;
     }
 
+    protected SamlSessionStore createSessionStore(Request request, HttpFacade facade, SamlDeployment resolvedDeployment) {
+        SamlSessionStore store;
+        store = new CatalinaSamlSessionStore(userSessionManagement, createPrincipalFactory(), mapper, request, this, facade, resolvedDeployment);
+        return store;
+    }
+
 }
diff --git a/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java b/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
index 804acf3..340c811 100755
--- a/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
+++ b/adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java
@@ -32,15 +32,18 @@ public class CatalinaSamlSessionStore implements SamlSessionStore {
     protected final Request request;
     protected final AbstractSamlAuthenticatorValve valve;
     protected final HttpFacade facade;
+    protected final SamlDeployment deployment;
 
     public CatalinaSamlSessionStore(CatalinaUserSessionManagement sessionManagement, GenericPrincipalFactory principalFactory,
-                                    SessionIdMapper idMapper, Request request, AbstractSamlAuthenticatorValve valve, HttpFacade facade) {
+                                    SessionIdMapper idMapper, Request request, AbstractSamlAuthenticatorValve valve, HttpFacade facade,
+                                    SamlDeployment deployment) {
         this.sessionManagement = sessionManagement;
         this.principalFactory = principalFactory;
         this.idMapper = idMapper;
         this.request = request;
         this.valve = valve;
         this.facade = facade;
+        this.deployment = deployment;
     }
 
     @Override
@@ -173,10 +176,15 @@ public class CatalinaSamlSessionStore implements SamlSessionStore {
         }
         request.setUserPrincipal(principal);
         request.setAuthType("KEYCLOAK-SAML");
-        idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), session.getId());
+        String newId = changeSessionId(session);
+        idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), newId);
 
     }
 
+    protected String changeSessionId(Session session) {
+        return session.getId();
+    }
+
     @Override
     public SamlSession getAccount() {
         HttpSession session = getSession(true);
diff --git a/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java b/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java
index 589835d..a7abb47 100755
--- a/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java
+++ b/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java
@@ -35,7 +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.ChangeSessionId;
 import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
 import org.keycloak.saml.common.exceptions.ParsingException;
 
@@ -184,7 +184,7 @@ public class SamlServletExtension implements ServletExtension {
         ServletSessionConfig cookieConfig = new ServletSessionConfig();
         cookieConfig.setPath(deploymentInfo.getContextPath());
         deploymentInfo.setServletSessionConfig(cookieConfig);
-        ChangeSessionIdOnLogin.turnOffChangeSessionIdOnLogin(deploymentInfo);
+        ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
 
      }
 
diff --git a/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java b/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java
index 9fe9085..491e35e 100755
--- a/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java
+++ b/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java
@@ -32,7 +32,7 @@ public class ServletSamlAuthMech extends AbstractSamlAuthMech {
 
     @Override
     protected SamlSessionStore getTokenStore(HttpServerExchange exchange, HttpFacade facade, SamlDeployment deployment, SecurityContext securityContext) {
-        return new ServletSamlSessionStore(exchange, sessionManagement, securityContext, idMapper);
+        return new ServletSamlSessionStore(exchange, sessionManagement, securityContext, idMapper, deployment);
     }
 
     @Override
diff --git a/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java b/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
index d9885d8..cd6f217 100755
--- a/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
+++ b/adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java
@@ -7,9 +7,11 @@ import io.undertow.server.session.SessionManager;
 import io.undertow.servlet.handlers.ServletRequestContext;
 import io.undertow.servlet.spec.HttpSessionImpl;
 import org.jboss.logging.Logger;
+import org.keycloak.adapters.saml.SamlDeployment;
 import org.keycloak.adapters.spi.SessionIdMapper;
 import org.keycloak.adapters.saml.SamlSession;
 import org.keycloak.adapters.saml.SamlSessionStore;
+import org.keycloak.adapters.undertow.ChangeSessionId;
 import org.keycloak.adapters.undertow.SavedRequest;
 import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
 import org.keycloak.common.util.KeycloakUriBuilder;
@@ -36,15 +38,17 @@ public class ServletSamlSessionStore implements SamlSessionStore {
     private final UndertowUserSessionManagement sessionManagement;
     private final SecurityContext securityContext;
     private final SessionIdMapper idMapper;
+    protected final SamlDeployment deployment;
 
 
     public ServletSamlSessionStore(HttpServerExchange exchange, UndertowUserSessionManagement sessionManagement,
                                    SecurityContext securityContext,
-                                   SessionIdMapper idMapper) {
+                                   SessionIdMapper idMapper, SamlDeployment deployment) {
         this.exchange = exchange;
         this.sessionManagement = sessionManagement;
         this.securityContext = securityContext;
         this.idMapper = idMapper;
+        this.deployment = deployment;
     }
 
     @Override
@@ -155,10 +159,16 @@ public class ServletSamlSessionStore implements SamlSessionStore {
         HttpSession session = getSession(true);
         session.setAttribute(SamlSession.class.getName(), account);
         sessionManagement.login(servletRequestContext.getDeployment().getSessionManager());
-        idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), session.getId());
+        String sessionId = changeSessionId(session);
+        idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), sessionId);
 
     }
 
+    protected String changeSessionId(HttpSession session) {
+        if (deployment.turnOffChangeSessionIdOnLogin() == false) return ChangeSessionId.changeSessionId(exchange, false);
+        else return session.getId();
+    }
+
     @Override
     public SamlSession getAccount() {
         HttpSession session = getSession(true);
diff --git a/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlAuthMech.java b/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlAuthMech.java
index e532233..46b82af 100755
--- a/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlAuthMech.java
+++ b/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlAuthMech.java
@@ -20,6 +20,6 @@ public class WildflySamlAuthMech extends ServletSamlAuthMech {
 
     @Override
     protected SamlSessionStore getTokenStore(HttpServerExchange exchange, HttpFacade facade, SamlDeployment deployment, SecurityContext securityContext) {
-        return new WildflySamlSessionStore(exchange, sessionManagement, securityContext, idMapper);
+        return new WildflySamlSessionStore(exchange, sessionManagement, securityContext, idMapper, deployment);
     }
 }
diff --git a/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlSessionStore.java b/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlSessionStore.java
index 4551333..8d038af 100755
--- a/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlSessionStore.java
+++ b/adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlSessionStore.java
@@ -2,6 +2,7 @@ package org.keycloak.adapters.saml.wildfly;
 
 import io.undertow.security.api.SecurityContext;
 import io.undertow.server.HttpServerExchange;
+import org.keycloak.adapters.saml.SamlDeployment;
 import org.keycloak.adapters.spi.SessionIdMapper;
 import org.keycloak.adapters.saml.SamlSession;
 import org.keycloak.adapters.saml.undertow.ServletSamlSessionStore;
@@ -13,8 +14,8 @@ import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
  */
 public class WildflySamlSessionStore extends ServletSamlSessionStore {
     public WildflySamlSessionStore(HttpServerExchange exchange, UndertowUserSessionManagement sessionManagement,
-                                   SecurityContext securityContext, SessionIdMapper idMapper) {
-        super(exchange, sessionManagement, securityContext, idMapper);
+                                   SecurityContext securityContext, SessionIdMapper idMapper, SamlDeployment resolvedDeployment) {
+        super(exchange, sessionManagement, securityContext, idMapper, resolvedDeployment);
     }
 
     @Override
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java
old mode 100644
new mode 100755
index 9b89fb2..14518f6
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java
@@ -30,6 +30,8 @@ public class Constants {
         static final String NAME_ID_POLICY_FORMAT = "name-id-policy-format";
         static final String LOGOUT_PAGE = "logout-page";
         static final String FORCE_AUTHENTICATION = "force-authentication";
+        static final String IS_PASSIVE = "isPassive";
+        static final String TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN = "turnOffChangeSessionIdOnLogin";
         static final String ROLE_ATTRIBUTES = "role-attributes";
         static final String SIGNING = "signing";
         static final String ENCRYPTION = "encryption";
@@ -87,6 +89,8 @@ public class Constants {
         static final String KEY_STORE = "KeyStore";
         static final String PRIVATE_KEY = "PrivateKey";
         static final String CERTIFICATE = "Certificate";
+        static final String IS_PASSIVE = "isPassive";
+        static final String TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN = "turnOffChangeSessionIdOnLogin";
 
         static final String PRIVATE_KEY_ALIAS = "alias";
         static final String PRIVATE_KEY_PASSWORD = "password";
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/ServiceProviderDefinition.java b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/ServiceProviderDefinition.java
old mode 100644
new mode 100755
index cb84f12..56abc84
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/ServiceProviderDefinition.java
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/ServiceProviderDefinition.java
@@ -59,6 +59,15 @@ public class ServiceProviderDefinition extends SimpleResourceDefinition {
                     .setXmlName(Constants.XML.FORCE_AUTHENTICATION)
                     .build();
 
+    static final SimpleAttributeDefinition IS_PASSIVE =
+            new SimpleAttributeDefinitionBuilder(Constants.Model.IS_PASSIVE, ModelType.BOOLEAN, true)
+                    .setXmlName(Constants.XML.IS_PASSIVE)
+                    .build();
+    static final SimpleAttributeDefinition TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN =
+            new SimpleAttributeDefinitionBuilder(Constants.Model.TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN, ModelType.BOOLEAN, true)
+                    .setXmlName(Constants.XML.TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN)
+                    .build();
+
     static final SimpleAttributeDefinition PRINCIPAL_NAME_MAPPING_POLICY =
             new SimpleAttributeDefinitionBuilder(Constants.Model.PRINCIPAL_NAME_MAPPING_POLICY, ModelType.STRING, true)
                     .setXmlName(Constants.XML.PRINCIPAL_NAME_MAPPING_POLICY)
@@ -74,7 +83,7 @@ public class ServiceProviderDefinition extends SimpleResourceDefinition {
                     .setAllowNull(false)
                     .build();
 
-    static final SimpleAttributeDefinition[] ATTRIBUTES = {SSL_POLICY, NAME_ID_POLICY_FORMAT, LOGOUT_PAGE, FORCE_AUTHENTICATION};
+    static final SimpleAttributeDefinition[] ATTRIBUTES = {SSL_POLICY, NAME_ID_POLICY_FORMAT, LOGOUT_PAGE, FORCE_AUTHENTICATION, IS_PASSIVE, TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN};
     static final AttributeDefinition[] ELEMENTS = {PRINCIPAL_NAME_MAPPING_POLICY, PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME, ROLE_ATTRIBUTES};
 
 
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties
index f8a4a11..f4d9f32 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties
@@ -15,6 +15,8 @@ keycloak-saml.service-provider.ssl-policy=SSL Policy to use
 keycloak-saml.service-provider.name-id-policy-format=Name ID policy format URN
 keycloak-saml.service-provider.logout-page=URI to a logout page
 keycloak-saml.service-provider.force-authentication=Redirected unauthenticated request to a login page
+keycloak-saml.service-provider.isPassive=If user isn't logged in just return with an error.  Used to check if a user is already logged in or not
+keycloak-saml.service-provider.turnOffChangeSessionIdOnLogin=The session id is changed by default on a successful login.  Change this to true if you want to turn this off
 keycloak-saml.service-provider.role-attributes=Role identifiers
 keycloak-saml.service-provider.principal-name-mapping-policy=Principal name mapping policy
 keycloak-saml.service-provider.principal-name-mapping-attribute-name=Principal name mapping attribute name
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
index 725104b..9fa34ba 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
@@ -66,6 +66,16 @@
                 <xs:documentation>Redirected unauthenticated request to a login page</xs:documentation>
             </xs:annotation>
         </xs:attribute>
+        <xs:attribute name="isPassive" type="xs:boolean" use="required">
+            <xs:annotation>
+                <xs:documentation>If user isn't logged in just return with an error.  Used to check if a user is already logged in or not</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="turnOffChangeSessionIdOnLogin" type="xs:boolean" use="required">
+            <xs:annotation>
+                <xs:documentation>The session id is changed by default on a successful login.  Change this to true if you want to turn this off</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
     </xs:complexType>
     <xs:complexType name="identity-provider-type">
         <xs:all minOccurs="1" maxOccurs="1">
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml b/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml
old mode 100644
new mode 100755
index 6f56fb0..eead9bf
--- a/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml
@@ -4,7 +4,9 @@
             sslPolicy="EXTERNAL"
             nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
             logoutPage="/logout.jsp"
-            forceAuthentication="false">
+            forceAuthentication="false"
+            isPassive="true"
+            turnOffChangeSessionIdOnLogin="true">
 
             <Keys>
                 <Key encryption="true" signing="true">
diff --git a/adapters/spi/pom.xml b/adapters/spi/pom.xml
index f387e86..58ed45b 100755
--- a/adapters/spi/pom.xml
+++ b/adapters/spi/pom.xml
@@ -19,5 +19,6 @@
         <module>undertow-adapter-spi</module>
         <module>servlet-adapter-spi</module>
         <module>jboss-adapter-core</module>
+        <module>jetty-adapter-spi</module>
     </modules>
 </project>
diff --git a/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java b/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java
index dcdb709..c6aaa8c 100755
--- a/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java
+++ b/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java
@@ -50,6 +50,8 @@ public class AdapterConfig extends BaseAdapterConfig {
     protected String tokenStore;
     @JsonProperty("principal-attribute")
     protected String principalAttribute;
+    @JsonProperty("turn-off-change-session-id-on-login")
+    protected Boolean turnOffChangeSessionIdOnLogin;
 
     public boolean isAllowAnyHostname() {
         return allowAnyHostname;
@@ -162,4 +164,12 @@ public class AdapterConfig extends BaseAdapterConfig {
     public void setPrincipalAttribute(String principalAttribute) {
         this.principalAttribute = principalAttribute;
     }
+
+    public Boolean getTurnOffChangeSessionIdOnLogin() {
+        return turnOffChangeSessionIdOnLogin;
+    }
+
+    public void setTurnOffChangeSessionIdOnLogin(Boolean turnOffChangeSessionIdOnLogin) {
+        this.turnOffChangeSessionIdOnLogin = turnOffChangeSessionIdOnLogin;
+    }
 }
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/adapter-config.xml b/docbook/auth-server-docs/reference/en/en-US/modules/adapter-config.xml
index f0f6c99..f20469b 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/adapter-config.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/adapter-config.xml
@@ -379,6 +379,15 @@
                     </para>
                 </listitem>
             </varlistentry>
+            <varlistentry>
+                <term>turn-off-change-session-id-on-login</term>
+                <listitem>
+                    <para>
+                        The session id is changed by default on a successful login on some platforms to plug a security attack vector (Tomcat 8, Jetty9, Undertow/Wildfly).  Change this to true if you want to turn this off
+                        This is <emphasis>OPTIONAL</emphasis>. The default value is <emphasis>false</emphasis>.
+                    </para>
+                </listitem>
+            </varlistentry>
         </variablelist>
     </para>
 </section>
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index 544abfa..69ac705 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -104,6 +104,14 @@
                     with mongo and infinispan under modules keycloak-model-mongo and keycloak-model-infinispan.
                 </para>
             </simplesect>
+            <simplesect>
+                <title>For adapters, session id changed after login</title>
+                <para>
+                    To plug a security attack vector, for platforms that support it (Tomcat 8, Undertow/Wildfly, Jetty 9),
+                    the keycloak oidc and saml adapters will change the session id after login.  You can turn off this behavior
+                    check adapter config switches.
+                </para>
+            </simplesect>
         </section>
         <section>
             <title>Migrating to 1.8.0</title>
diff --git a/docbook/saml-adapter-docs/reference/en/en-US/modules/adapter-config.xml b/docbook/saml-adapter-docs/reference/en/en-US/modules/adapter-config.xml
index 5335362..f79561b 100755
--- a/docbook/saml-adapter-docs/reference/en/en-US/modules/adapter-config.xml
+++ b/docbook/saml-adapter-docs/reference/en/en-US/modules/adapter-config.xml
@@ -12,7 +12,8 @@
         nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
         logoutPage="/logout.jsp"
         forceAuthentication="false"
-        isPassive="false">
+        isPassive="false"
+        turnOffChangeSessionIdOnLogin="false">
         <Keys>
             <Key signing="true" >
                 <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
@@ -125,6 +126,15 @@
                         </para>
                     </listitem>
                 </varlistentry>
+                <varlistentry>
+                    <term>turnOffChangeSessionIdOnLogin</term>
+                    <listitem>
+                        <para>
+                            The session id is changed by default on a successful login on some platforms to plug a security attack vector (Tomcat 8, Jetty9, Undertow/Wildfly).  Change this to true if you want to turn this off
+                            This is <emphasis>OPTIONAL</emphasis>. The default value is <emphasis>false</emphasis>.
+                        </para>
+                    </listitem>
+                </varlistentry>
             </variablelist>
         </para>
     </section>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputPage.java
new file mode 100755
index 0000000..dd929e1
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputPage.java
@@ -0,0 +1,35 @@
+package org.keycloak.testsuite.keycloaksaml;
+
+import org.keycloak.testsuite.pages.AbstractPage;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class InputPage extends AbstractPage {
+    @FindBy(id = "parameter")
+    private WebElement parameter;
+
+    @FindBy(name = "submit")
+    private WebElement submit;
+
+    public void execute(String param) {
+        parameter.clear();
+        parameter.sendKeys(param);
+
+        submit.click();
+    }
+
+
+    public boolean isCurrent() {
+        return driver.getTitle().equals("Input Page");
+    }
+
+    @Override
+    public void open() {
+    }
+
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputServlet.java
new file mode 100755
index 0000000..5da5b97
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputServlet.java
@@ -0,0 +1,52 @@
+package org.keycloak.testsuite.keycloaksaml;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
+ */
+public class InputServlet extends HttpServlet {
+
+    private static final String FORM_URLENCODED = "application/x-www-form-urlencoded";
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        String appBase = System.getProperty("app.server.base.url", "http://localhost:8081");
+        String actionUrl = appBase + "/input-portal/secured/post";
+
+
+        resp.setContentType("text/html");
+        PrintWriter pw = resp.getWriter();
+        pw.printf("<html><head><title>%s</title></head><body>", "Input Page");
+        pw.printf("<form action=\"%s\" method=\"POST\">", actionUrl);
+        pw.println("<input id=\"parameter\" type=\"text\" name=\"parameter\">");
+        pw.println("<input name=\"submit\" type=\"submit\" value=\"Submit\"></form>");
+        pw.print("</body></html>");
+        pw.flush();
+
+
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        if (!FORM_URLENCODED.equals(req.getContentType())) {
+            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            PrintWriter pw = resp.getWriter();
+            resp.setContentType("text/plain");
+            pw.printf("Expecting content type " + FORM_URLENCODED +
+                    ", received " + req.getContentType() + " instead");
+            pw.flush();
+            return;
+        }
+        resp.setContentType("text/plain");
+        PrintWriter pw = resp.getWriter();
+        pw.printf("parameter="+req.getParameter("parameter"));
+        pw.flush();
+    }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
index 9f23b70..82a1006 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
@@ -31,6 +31,8 @@ public class SamlAdapterTest {
             initializeSamlSecuredWar("/keycloak-saml/bad-client-signed-post", "/bad-client-sales-post-sig",  "bad-client-post-sig.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/bad-realm-signed-post", "/bad-realm-sales-post-sig",  "bad-realm-post-sig.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/encrypted-post", "/sales-post-enc",  "post-enc.war", classLoader);
+            System.setProperty("app.server.base.url", "http://localhost:8081");
+            initializeSamlSecuredWar("/keycloak-saml/simple-input", "/input-portal",  "input.war", classLoader, InputServlet.class, "/secured/*");
             SamlAdapterTestStrategy.uploadSP("http://localhost:8081/auth");
             server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
 
@@ -63,6 +65,11 @@ public class SamlAdapterTest {
         });
     }
 
+
+    //@Test Doesn't work for Wildfly as the input stream is read by getParameter for SAML POST binding
+    public void testSavedPostRequest() throws Exception {
+        testStrategy.testSavedPostRequest();
+    }
     @Test
     public void testErrorHandling() throws Exception {
         testStrategy.testErrorHandling();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
index 646c42b..9f07239 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
@@ -3,6 +3,7 @@ package org.keycloak.testsuite.keycloaksaml;
 import org.apache.commons.io.IOUtils;
 import org.junit.Assert;
 import org.junit.rules.ExternalResource;
+import org.keycloak.OAuth2Constants;
 import org.keycloak.adapters.saml.SamlAuthenticationError;
 import org.keycloak.adapters.saml.SamlPrincipal;
 import org.keycloak.admin.client.Keycloak;
@@ -12,6 +13,7 @@ import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
 import org.keycloak.protocol.saml.mappers.GroupMembershipMapper;
 import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
@@ -27,6 +29,7 @@ import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.KeycloakServer;
+import org.keycloak.testsuite.adapter.*;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 import org.keycloak.testsuite.rule.ErrorServlet;
@@ -38,7 +41,10 @@ import org.w3c.dom.Document;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Form;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
 import java.io.IOException;
 import java.net.URI;
 import java.util.HashSet;
@@ -70,6 +76,8 @@ public class SamlAdapterTestStrategy  extends ExternalResource {
     protected WebDriver driver;
     @WebResource
     protected LoginPage loginPage;
+    @WebResource
+    protected InputPage inputPage;
 
     @Override
     protected void before() throws Throwable {
@@ -101,6 +109,38 @@ public class SamlAdapterTestStrategy  extends ExternalResource {
         Assert.assertTrue(driver.getCurrentUrl().startsWith(AUTH_SERVER_URL + "/realms/demo/protocol/saml"));
     }
 
+    public void testSavedPostRequest() throws Exception {
+        // test login to customer-portal which does a bearer request to customer-db
+        driver.navigate().to(APP_SERVER_BASE_URL + "/input-portal");
+        System.out.println("Current url: " + driver.getCurrentUrl());
+        Assert.assertTrue(driver.getCurrentUrl().startsWith(APP_SERVER_BASE_URL + "/input-portal"));
+        inputPage.execute("hello");
+
+        assertEquals(driver.getCurrentUrl(), AUTH_SERVER_URL + "/realms/demo/protocol/saml");
+        loginPage.login("bburke@redhat.com", "password");
+        System.out.println("Current url: " + driver.getCurrentUrl());
+        Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/input-portal/secured/post");
+        String pageSource = driver.getPageSource();
+        System.out.println(pageSource);
+        Assert.assertTrue(pageSource.contains("parameter=hello"));
+
+        // test logout
+
+        driver.navigate().to(APP_SERVER_BASE_URL + "/input-portal?GLO=true");
+
+        // test unsecured POST KEYCLOAK-901
+
+        Client client = ClientBuilder.newClient();
+        Form form = new Form();
+        form.param("parameter", "hello");
+        String text = client.target(APP_SERVER_BASE_URL + "/input-portal/unsecured").request().post(Entity.form(form), String.class);
+        Assert.assertTrue(text.contains("parameter=hello"));
+        client.close();
+
+    }
+
+
+
     public void testErrorHandling() throws Exception {
         ErrorServlet.authError = null;
         Client client = ClientBuilder.newClient();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
index 5a1d01f..2b8b42d 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java
@@ -15,6 +15,7 @@ import io.undertow.servlet.api.WebResourceCollection;
 import org.keycloak.adapters.saml.undertow.SamlServletExtension;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 
+import javax.servlet.Servlet;
 import java.io.IOException;
 import java.net.URL;
 
@@ -92,12 +93,19 @@ public abstract class SamlKeycloakRule extends AbstractKeycloakRule {
 
     public void initializeSamlSecuredWar(String warResourcePath, String contextPath, String warDeploymentName, ClassLoader classLoader) {
 
-        ServletInfo regularServletInfo = new ServletInfo("servlet", SendUsernameServlet.class)
+        Class<SendUsernameServlet> servletClass = SendUsernameServlet.class;
+        String constraintUrl = "/*";
+
+        initializeSamlSecuredWar(warResourcePath, contextPath, warDeploymentName, classLoader, servletClass, constraintUrl);
+    }
+
+    public void initializeSamlSecuredWar(String warResourcePath, String contextPath, String warDeploymentName, ClassLoader classLoader, Class<? extends Servlet> servletClass, String constraintUrl) {
+        ServletInfo regularServletInfo = new ServletInfo("servlet", servletClass)
                 .addMapping("/*");
 
         SecurityConstraint constraint = new SecurityConstraint();
         WebResourceCollection collection = new WebResourceCollection();
-        collection.addUrlPattern("/*");
+        collection.addUrlPattern(constraintUrl);
         constraint.addWebResourceCollection(collection);
         constraint.addRoleAllowed("manager");
         constraint.addRoleAllowed("el-jefe");
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/simple-input/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/simple-input/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000..fc8be19
--- /dev/null
+++ b/testsuite/integration/src/test/resources/keycloak-saml/simple-input/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,24 @@
+<keycloak-saml-adapter>
+    <SP entityID="http://localhost:8081/input-portal/"
+        sslPolicy="EXTERNAL"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        logoutPage="/logout.jsp"
+        forceAuthentication="false">
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp">
+            <SingleSignOnService requestBinding="POST"
+                                 bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    />
+
+            <SingleLogoutService
+                    requestBinding="POST"
+                    responseBinding="POST"
+                    postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    />
+        </IDP>
+     </SP>
+</keycloak-saml-adapter>
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
index 7a50a91..4df617d 100755
--- a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
+++ b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
@@ -86,6 +86,23 @@
             }
         },
         {
+            "name": "http://localhost:8081/input-portal/",
+            "enabled": true,
+            "fullScopeAllowed": true,
+            "protocol": "saml",
+            "baseUrl": "http://localhost:8081/input-portal/",
+            "redirectUris": [
+                "http://localhost:8081/input-portal/*"
+            ],
+            "attributes": {
+                "saml.authnstatement": "true",
+                "saml_assertion_consumer_url_post": "http://localhost:8081/input-portal/",
+                "saml_assertion_consumer_url_redirect": "http://localhost:8081/input-portal/",
+                "saml_single_logout_service_url_post": "http://localhost:8081/input-portal/",
+                "saml_single_logout_service_url_redirect": "http://localhost:8081/input-portal/"
+            }
+        },
+        {
             "name": "http://localhost:8081/sales-post-passive/",
             "enabled": true,
             "fullScopeAllowed": true,