KEYCLOAK-14103 Add Warn message for possibly missing SameSite configuration

This commit is contained in:
mhajas 2020-06-03 16:46:09 +02:00 committed by Hynek Mlnařík
parent bfde3ac080
commit 5d1d75db40
17 changed files with 148 additions and 10 deletions

View file

@ -288,6 +288,10 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
}
}
log.warn("Keycloak Adapter obtained Response, that is not understood. This may be because the containers " +
"cookies are not properly configured with SameSite settings. Refer to KEYCLOAK-14103 for more details.");
return AuthOutcome.NOT_ATTEMPTED;
}
@ -352,6 +356,12 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
}
protected AuthOutcome handleLoginResponse(SAMLDocumentHolder responseHolder, boolean postBinding, OnSessionCreated onCreateSession) {
if (!sessionStore.isLoggingIn()) {
log.warn("Adapter obtained LoginResponse, however containers session is not aware of sending any request. " +
"This may be because the session cookies created by container are not properly configured " +
"with SameSite settings. Refer to KEYCLOAK-14103 for more details.");
}
final ResponseType responseType = (ResponseType) responseHolder.getSamlObject();
AssertionType assertion = null;
if (! isSuccessfulSamlResponse(responseType) || responseType.getAssertions() == null || responseType.getAssertions().isEmpty()) {

View file

@ -0,0 +1,43 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
version="2.0"
exclude-result-prefixes="xalan">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="4" standalone="no" />
<xsl:strip-space elements="*"/>
<xsl:template match="//*[local-name()='Service']">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<Connector port="8643" maxThreads="500"
server="Apache"
scheme="https" secure="true" SSLEnabled="true" acceptCount="500"
keystoreFile="conf/adapter.jks" keystorePass="secret"
truststoreFile="conf/keycloak.truststore" truststorePass="secret"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

View file

@ -318,5 +318,73 @@
</modules>
</profile>
<profile>
<id>configure-ssl</id>
<activation>
<property>
<name>app.server.ssl.required</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<id>configure-https-connector</id>
<phase>process-test-resources</phase>
<goals>
<goal>transform</goal>
</goals>
<configuration>
<transformationSets>
<transformationSet>
<dir>${app.server.tomcat.home}/conf</dir>
<stylesheet>${common.resources}/tomcat-add-connector.xsl</stylesheet>
<includes>
<include>server.xml</include>
</includes>
<outputDir>${app.server.tomcat.home}/conf</outputDir>
</transformationSet>
</transformationSets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-keycloak-truststore</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${app.server.tomcat.home}/conf</outputDirectory>
<resources>
<resource>
<directory>${common.resources}/keystore</directory>
<includes>
<include>keycloak.truststore</include>
<include>adapter.jks</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>truststore</nonFilteredFileExtension>
<nonFilteredFileExtension>jks</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View file

@ -48,6 +48,10 @@
<cache.default.worker.task-max-threads>4</cache.default.worker.task-max-threads>
<jboss.cli.executable>jboss-cli.sh</jboss.cli.executable>
<!-- Tomcat versions needs to be overwritten to newer versions because of https://issues.redhat.com/browse/KEYCLOAK-14103 -->
<tomcat9.version>9.0.29</tomcat9.version>
<tomcat8.version>8.5.49</tomcat8.version>
</properties>
<modules>

View file

@ -60,6 +60,7 @@ public class AppServerTestEnricher {
private static final Logger log = Logger.getLogger(AppServerTestEnricher.class);
public static final String CURRENT_APP_SERVER = System.getProperty("app.server", "undertow");
public static final boolean APP_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("app.server.ssl.required", "false"));
@Inject private Instance<ContainerController> containerConrollerInstance;
@Inject private Instance<TestContext> testContextInstance;

View file

@ -21,6 +21,7 @@ import org.jboss.logging.Logger;
import org.junit.Assume;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.APP_SERVER_SSL_REQUIRED;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_SSL_REQUIRED;
public class ContainerAssume {
@ -51,4 +52,8 @@ public class ContainerAssume {
public static void assumeAuthServerSSL() {
Assume.assumeTrue("Only works with the SSL configured", AUTH_SERVER_SSL_REQUIRED);
}
public static void assumeAppServerSSL() {
Assume.assumeTrue("Only works with the SSL configured", APP_SERVER_SSL_REQUIRED);
}
}

View file

@ -48,6 +48,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.APP_SERVER_SSL_REQUIRED;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_SSL_REQUIRED;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
@ -64,12 +66,14 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
@Page
protected AppServerContextRoot appServerContextRootPage;
protected static final boolean APP_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("app.server.ssl.required", "false"));
protected static final String APP_SERVER_CONTAINER = System.getProperty("app.server", "");
public static final String JBOSS_DEPLOYMENT_STRUCTURE_XML = "jboss-deployment-structure.xml";
public static final URL jbossDeploymentStructure = AbstractServletsAdapterTest.class
.getResource("/adapter-test/" + JBOSS_DEPLOYMENT_STRUCTURE_XML);
public static final String UNDERTOW_HANDLERS_CONF = "undertow-handlers.conf";
public static final URL undertowHandlersConf = AbstractServletsAdapterTest.class
.getResource("/adapter-test/samesite/undertow-handlers.conf");
public static final String TOMCAT_CONTEXT_XML = "context.xml";
public static final URL tomcatContext = AbstractServletsAdapterTest.class
.getResource("/adapter-test/" + TOMCAT_CONTEXT_XML);

View file

@ -6,6 +6,7 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.BeforeClass;
import org.junit.Test;
import org.keycloak.adapters.rotation.PublicKeyLocator;
import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
import org.keycloak.testsuite.adapter.page.Employee2Servlet;
import org.keycloak.testsuite.adapter.page.EmployeeSigServlet;
@ -20,6 +21,7 @@ import org.openqa.selenium.By;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getAppServerContextRoot;
@ -33,13 +35,9 @@ import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
/**
* @author mhajas
*/
@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
@AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY)
@AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY_DEPRECATED)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP6)
@AppServerContainer(ContainerConstants.APP_SERVER_EAP71)
@AppServerContainer(ContainerConstants.APP_SERVER_TOMCAT7)
// @AppServerContainer(ContainerConstants.APP_SERVER_EAP) // Should be added in: KEYCLOAK-14434
// @AppServerContainer(ContainerConstants.APP_SERVER_EAP6) // Should be added in: KEYCLOAK-14435
@AppServerContainer(ContainerConstants.APP_SERVER_TOMCAT8)
@AppServerContainer(ContainerConstants.APP_SERVER_TOMCAT9)
@AuthServerContainerExclude(AuthServerContainerExclude.AuthServer.REMOTE)
@ -50,12 +48,14 @@ public class SAMLSameSiteTest extends AbstractSAMLServletAdapterTest {
@Deployment(name = Employee2Servlet.DEPLOYMENT_NAME)
protected static WebArchive employee2() {
return samlServletDeployment(Employee2Servlet.DEPLOYMENT_NAME, WEB_XML_WITH_ACTION_FILTER, SendUsernameServlet.class, AdapterActionsFilter.class, PublicKeyLocator.class);
return samlServletDeployment(Employee2Servlet.DEPLOYMENT_NAME, WEB_XML_WITH_ACTION_FILTER, SendUsernameServlet.class, AdapterActionsFilter.class, PublicKeyLocator.class)
.addAsWebInfResource(undertowHandlersConf, UNDERTOW_HANDLERS_CONF);
}
@Deployment(name = EmployeeSigServlet.DEPLOYMENT_NAME)
protected static WebArchive employeeSig() {
return samlServletDeployment(EmployeeSigServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
return samlServletDeployment(EmployeeSigServlet.DEPLOYMENT_NAME, SendUsernameServlet.class)
.addAsWebInfResource(undertowHandlersConf, UNDERTOW_HANDLERS_CONF);
}
@Page
@ -64,6 +64,7 @@ public class SAMLSameSiteTest extends AbstractSAMLServletAdapterTest {
@BeforeClass
public static void enabledOnlyWithSSL() {
ContainerAssume.assumeAuthServerSSL();
ContainerAssume.assumeAppServerSSL();
}
@Test

View file

@ -17,4 +17,5 @@
<Context path="/%CONTEXT_PATH%">
<Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
<CookieProcessor sameSiteCookies="None" />
</Context>

View file

@ -0,0 +1 @@
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)