keycloak-aplcache
Changes
adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java 10(+10 -0)
adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java 3(+3 -0)
adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java 2(+1 -1)
adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/Jetty91RequestAuthenticator.java 30(+30 -0)
adapters/oidc/jetty/jetty9.1/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java 9(+9 -0)
adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/Jetty92RequestAuthenticator.java 30(+30 -0)
adapters/oidc/jetty/jetty9.2/src/main/java/org/keycloak/adapters/jetty/KeycloakJettyAuthenticator.java 9(+9 -0)
adapters/oidc/jetty/jetty-core/src/main/java/org/keycloak/adapters/jetty/core/JettyRequestAuthenticator.java 2(+1 -1)
adapters/oidc/jetty/pom.xml 1(+0 -1)
adapters/oidc/servlet-filter/src/main/java/org/keycloak/adapters/servlet/FilterRequestAuthenticator.java 2(+1 -1)
adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticator.java 2(+1 -1)
adapters/oidc/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/SpringSecurityRequestAuthenticatorTest.java 4(+2 -2)
adapters/oidc/tomcat/tomcat6/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java 3(+3 -0)
adapters/oidc/tomcat/tomcat7/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java 3(+3 -0)
adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/KeycloakAuthenticatorValve.java 8(+8 -0)
adapters/oidc/tomcat/tomcat8/src/main/java/org/keycloak/adapters/tomcat/Tomcat8RequestAuthenticator.java 28(+28 -0)
adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/AbstractKeycloakAuthenticatorValve.java 14(+12 -2)
adapters/oidc/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/tomcat/CatalinaRequestAuthenticator.java 2(+1 -1)
adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/AbstractUndertowRequestAuthenticator.java 2(+1 -1)
adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java 2(+1 -1)
adapters/oidc/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java 5(+5 -0)
adapters/oidc/wildfly/wf8-subsystem/src/main/java/org/keycloak/subsystem/wf8/extension/SecureDeploymentDefinition.java 7(+7 -0)
adapters/oidc/wildfly/wf8-subsystem/src/main/resources/org/keycloak/subsystem/wf8/extension/LocalDescriptions.properties 1(+1 -0)
adapters/oidc/wildfly/wf8-subsystem/src/test/resources/org/keycloak/subsystem/wf8/extension/keycloak-1.1.xml 1(+1 -0)
adapters/oidc/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/extension/SecureDeploymentDefinition.java 7(+7 -0)
adapters/oidc/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/extension/LocalDescriptions.properties 1(+1 -0)
adapters/oidc/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/extension/keycloak-1.1.xml 1(+1 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java 1(+1 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java 1(+1 -0)
adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java 27(+27 -0)
adapters/saml/jetty/jetty9.1/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java 10(+10 -0)
adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/Jetty9SamlSessionStore.java 27(+27 -0)
adapters/saml/jetty/jetty9.2/src/main/java/org/keycloak/adapters/saml/jetty/KeycloakSamlAuthenticator.java 9(+9 -0)
adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/AbstractSamlAuthenticator.java 8(+7 -1)
adapters/saml/jetty/jetty-core/src/main/java/org/keycloak/adapters/saml/jetty/JettySamlSessionStore.java 13(+10 -3)
adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/SamlAuthenticatorValve.java 12(+12 -0)
adapters/saml/tomcat/tomcat8/src/main/java/org/keycloak/adapters/saml/tomcat/Tomcat8SamlSessionStore.java 28(+28 -0)
adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/AbstractSamlAuthenticatorValve.java 14(+10 -4)
adapters/saml/tomcat/tomcat-core/src/main/java/org/keycloak/adapters/saml/CatalinaSamlSessionStore.java 12(+10 -2)
adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/SamlServletExtension.java 4(+2 -2)
adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java 2(+1 -1)
adapters/saml/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java 14(+12 -2)
adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlAuthMech.java 2(+1 -1)
adapters/saml/wildfly/wildfly-adapter/src/main/java/org/keycloak/adapters/saml/wildfly/WildflySamlSessionStore.java 5(+3 -2)
adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java 4(+4 -0)
adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/ServiceProviderDefinition.java 11(+10 -1)
adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties 2(+2 -0)
adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd 10(+10 -0)
adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml 4(+3 -1)
adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyHttpFacade.java 0(+0 -0)
adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/JettyUserSessionManagement.java 0(+0 -0)
adapters/spi/jetty-adapter-spi/src/main/java/org/keycloak/adapters/jetty/spi/WrappingSessionHandler.java 0(+0 -0)
adapters/spi/pom.xml 1(+1 -0)
adapters/spi/undertow-adapter-spi/src/main/java/org/keycloak/adapters/undertow/ChangeSessionId.java 28(+27 -1)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/InputServlet.java 52(+52 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java 7(+7 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java 40(+40 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlKeycloakRule.java 12(+10 -2)
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;
}
adapters/oidc/jetty/pom.xml 1(+0 -1)
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">
adapters/spi/pom.xml 1(+1 -0)
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,