keycloak-uncached
Changes
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeServletDistributable.java 49(+49 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/SAMLServlet.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java 237(+237 -0)
testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/keycloak-saml.xml 44(+44 -0)
testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml-behind-lb.json 164(+164 -0)
testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/cluster/EAP6SAMLAdapterClusterTest.java 102(+102 -0)
testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml 62(+62 -0)
testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/cluster/WildflySAMLAdapterClusterTest.java 97(+97 -0)
Details
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeServletDistributable.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeServletDistributable.java
new file mode 100644
index 0000000..ed547c0
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeServletDistributable.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package org.keycloak.testsuite.adapter.page;
+
+import org.jboss.arquillian.container.test.api.OperateOnDeployment;
+import org.jboss.arquillian.test.api.ArquillianResource;
+
+import java.net.URL;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * @author mhajas
+ */
+public class EmployeeServletDistributable extends SAMLServlet {
+ public static final String DEPLOYMENT_NAME = "employee-distributable";
+
+ @ArquillianResource
+ @OperateOnDeployment(DEPLOYMENT_NAME)
+ private URL url;
+
+ public EmployeeServletDistributable(WebDriver driver) {
+ super();
+ this.driver = driver;
+ }
+
+ @Override
+ public URL getInjectedUrl() {
+ return url;
+ }
+
+ public void setUrl(URL url) {
+ this.url = url;
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/SAMLServlet.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/SAMLServlet.java
index cc4a419..2f226b9 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/SAMLServlet.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/SAMLServlet.java
@@ -28,7 +28,7 @@ public abstract class SAMLServlet extends AbstractPageWithInjectedUrl {
public void logout() {
driver.navigate().to(getUriBuilder().queryParam("GLO", "true").build().toASCIIString());
- getUriBuilder().replaceQueryParam("GLO", null);
+ getUriBuilder().replaceQueryParam("GLO");
pause(300);
}
@@ -36,7 +36,7 @@ public abstract class SAMLServlet extends AbstractPageWithInjectedUrl {
if (check) {
getUriBuilder().queryParam("checkRoles", true);
} else {
- getUriBuilder().replaceQueryParam("checkRoles", null);
+ getUriBuilder().replaceQueryParam("checkRoles");
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
index bd6e5a0..e3950d3 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/DeploymentTargetModifier.java
@@ -51,7 +51,7 @@ public class DeploymentTargetModifier extends AnnotationDeploymentScenarioGenera
if (appServerQualifier != null && !appServerQualifier.isEmpty()) {
for (DeploymentDescription deployment : deployments) {
- if (deployment.getTarget() == null || !deployment.getTarget().getName().equals(appServerQualifier)) {
+ if (deployment.getTarget() == null || !deployment.getTarget().getName().startsWith(appServerQualifier)) {
log.debug("Setting target container for " + deployment.getName() + ": " + appServerQualifier);
deployment.setTarget(new TargetDescription(appServerQualifier));
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java
index cc018d2..235d15f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java
@@ -65,11 +65,11 @@ public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest {
return deployment;
}
- protected static WebArchive samlServletDeployment(String name, Class... servletClasses) {
+ public static WebArchive samlServletDeployment(String name, Class... servletClasses) {
return samlServletDeployment(name, "web.xml", servletClasses);
}
- protected static WebArchive samlServletDeployment(String name, String webXMLPath, Class... servletClasses) {
+ public static WebArchive samlServletDeployment(String name, String webXMLPath, Class... servletClasses) {
String baseSAMLPath = "/adapter-test/keycloak-saml/";
String webInfPath = baseSAMLPath + name + "/WEB-INF/";
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java
new file mode 100644
index 0000000..3868fb5
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/cluster/AbstractSAMLAdapterClusterTest.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2017 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.
+ */
+package org.keycloak.testsuite.adapter.servlet.cluster;
+
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.UsersResource;
+import org.keycloak.representations.idm.*;
+import org.keycloak.testsuite.Retry;
+import org.keycloak.testsuite.adapter.page.EmployeeServletDistributable;
+import org.keycloak.testsuite.adapter.page.SAMLServlet;
+import org.keycloak.testsuite.auth.page.AuthRealm;
+import org.keycloak.testsuite.auth.page.login.*;
+import org.keycloak.testsuite.page.AbstractPage;
+import org.keycloak.testsuite.util.WaitUtils;
+
+import io.undertow.Undertow;
+import io.undertow.server.handlers.ResponseCodeHandler;
+import io.undertow.server.handlers.proxy.LoadBalancingProxyClient;
+import io.undertow.server.handlers.proxy.ProxyHandler;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.function.Consumer;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.jboss.arquillian.container.test.api.*;
+import org.jboss.arquillian.graphene.page.Page;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.junit.*;
+
+import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
+import org.keycloak.testsuite.admin.ApiUtil;
+import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
+
+import org.openqa.selenium.TimeoutException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertThat;
+import static org.keycloak.testsuite.AbstractAuthTest.createUserRepresentation;
+import static org.keycloak.testsuite.admin.Users.setPasswordFor;
+import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getNearestSuperclassWithAnnotation;
+import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
+import static org.keycloak.testsuite.util.IOUtil.loadRealm;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+
+/**
+ *
+ * @author hmlnarik
+ */
+public abstract class AbstractSAMLAdapterClusterTest extends AbstractServletsAdapterTest {
+
+ protected static final String NODE_1_NAME = "ha-node-1";
+ protected static final String NODE_2_NAME = "ha-node-2";
+
+ protected final String NODE_1_SERVER_NAME = getAppServerId() + "-" + NODE_1_NAME;
+ protected final String NODE_2_SERVER_NAME = getAppServerId() + "-" + NODE_2_NAME;
+
+ protected static final int PORT_OFFSET_NODE_REVPROXY = NumberUtils.toInt(System.getProperty("app.server.reverse-proxy.port.offset"), -1);
+ protected static final int HTTP_PORT_NODE_REVPROXY = 8080 + PORT_OFFSET_NODE_REVPROXY;
+ protected static final int PORT_OFFSET_NODE_1 = NumberUtils.toInt(System.getProperty("app.server.1.port.offset"), -1);
+ protected static final int HTTP_PORT_NODE_1 = 8080 + PORT_OFFSET_NODE_1;
+ protected static final int PORT_OFFSET_NODE_2 = NumberUtils.toInt(System.getProperty("app.server.2.port.offset"), -1);
+ protected static final int HTTP_PORT_NODE_2 = 8080 + PORT_OFFSET_NODE_2;
+ protected static final URI NODE_1_URI = URI.create("http://localhost:" + HTTP_PORT_NODE_1);
+ protected static final URI NODE_2_URI = URI.create("http://localhost:" + HTTP_PORT_NODE_2);
+
+ @BeforeClass
+ public static void checkPropertiesSet() {
+ Assume.assumeThat(PORT_OFFSET_NODE_1, not(is(-1)));
+ Assume.assumeThat(PORT_OFFSET_NODE_2, not(is(-1)));
+ Assume.assumeThat(PORT_OFFSET_NODE_REVPROXY, not(is(-1)));
+ }
+
+ protected static void prepareServerDirectory(String targetSubdirectory) throws IOException {
+ Path path = Paths.get(System.getProperty("app.server.home"), targetSubdirectory);
+ File targetSubdirFile = path.toFile();
+ FileUtils.deleteDirectory(targetSubdirFile);
+ FileUtils.forceMkdir(targetSubdirFile);
+ FileUtils.copyDirectoryToDirectory(Paths.get(System.getProperty("app.server.home"), "standalone", "deployments").toFile(), targetSubdirFile);
+ }
+ protected LoadBalancingProxyClient loadBalancerToNodes;
+ protected Undertow reverseProxyToNodes;
+
+ @ArquillianResource
+ protected ContainerController controller;
+
+ @ArquillianResource
+ protected Deployer deployer;
+
+ @Page
+ LoginActions loginActionsPage;
+
+ @Override
+ public void addTestRealms(List<RealmRepresentation> testRealms) {
+ testRealms.add(loadRealm("/adapter-test/keycloak-saml/testsaml-behind-lb.json"));
+ }
+
+ @Before
+ public void prepareReverseProxy() throws Exception {
+ loadBalancerToNodes = new LoadBalancingProxyClient().addHost(NODE_1_URI, NODE_1_NAME).setConnectionsPerThread(10);
+ reverseProxyToNodes = Undertow.builder().addHttpListener(HTTP_PORT_NODE_REVPROXY, "localhost").setIoThreads(2).setHandler(new ProxyHandler(loadBalancerToNodes, 5000, ResponseCodeHandler.HANDLE_404)).build();
+ reverseProxyToNodes.start();
+ }
+
+ @After
+ public void stopReverseProxy() {
+ reverseProxyToNodes.stop();
+ }
+
+ @Before
+ public void startServer() throws Exception {
+ prepareServerDirectory("standalone-" + NODE_1_NAME);
+ controller.start(NODE_1_SERVER_NAME);
+ prepareWorkerNode(Integer.valueOf(System.getProperty("app.server.1.management.port")));
+ prepareServerDirectory("standalone-" + NODE_2_NAME);
+ controller.start(NODE_2_SERVER_NAME);
+ prepareWorkerNode(Integer.valueOf(System.getProperty("app.server.2.management.port")));
+ deployer.deploy(EmployeeServletDistributable.DEPLOYMENT_NAME);
+ deployer.deploy(EmployeeServletDistributable.DEPLOYMENT_NAME + "_2");
+ }
+
+ protected abstract void prepareWorkerNode(Integer managementPort) throws Exception;
+
+ @After
+ public void stopServer() {
+ controller.stop(NODE_1_SERVER_NAME);
+ controller.stop(NODE_2_SERVER_NAME);
+ }
+
+ @Override
+ public void setDefaultPageUriParameters() {
+ super.setDefaultPageUriParameters();
+
+ testRealmSAMLPostLoginPage.setAuthRealm(DEMO);
+ loginPage.setAuthRealm(DEMO);
+ loginActionsPage.setAuthRealm(DEMO);
+ }
+
+ protected void testLogoutViaSessionIndex(URL employeeUrl, Consumer<EmployeeServletDistributable> logoutFunction) {
+ EmployeeServletDistributable page = PageFactory.initElements(driver, EmployeeServletDistributable.class);
+ page.setUrl(employeeUrl);
+ page.getUriBuilder().port(HTTP_PORT_NODE_REVPROXY);
+
+ UserRepresentation bburkeUser = createUserRepresentation("bburke", "bburke@redhat.com", "Bill", "Burke", true);
+ setPasswordFor(bburkeUser, CredentialRepresentation.PASSWORD);
+
+ assertSuccessfulLogin(page, bburkeUser, testRealmSAMLPostLoginPage, "principal=bburke");
+
+ updateProxy(NODE_2_NAME, NODE_2_URI, NODE_1_URI);
+ logoutFunction.accept(page);
+ delayedCheckLoggedOut(page, loginActionsPage);
+
+ updateProxy(NODE_1_NAME, NODE_1_URI, NODE_2_URI);
+ delayedCheckLoggedOut(page, loginActionsPage);
+ }
+
+ @Test
+ public void testBackchannelLogout(@ArquillianResource
+ @OperateOnDeployment(value = EmployeeServletDistributable.DEPLOYMENT_NAME) URL employeeUrl) throws Exception {
+ testLogoutViaSessionIndex(employeeUrl, (EmployeeServletDistributable page) -> {
+ RealmResource demoRealm = adminClient.realm(DEMO);
+ String bburkeId = ApiUtil.findUserByUsername(demoRealm, "bburke").getId();
+ demoRealm.users().get(bburkeId).logout();
+ log.infov("Logged out via admin console");
+ });
+ }
+
+ @Test
+ public void testFrontchannelLogout(@ArquillianResource
+ @OperateOnDeployment(value = EmployeeServletDistributable.DEPLOYMENT_NAME) URL employeeUrl) throws Exception {
+ testLogoutViaSessionIndex(employeeUrl, (EmployeeServletDistributable page) -> {
+ page.logout();
+ log.infov("Logged out via application");
+ });
+ }
+
+ protected void updateProxy(String hostToPointToName, URI hostToPointToUri, URI hostToRemove) {
+ loadBalancerToNodes.removeHost(hostToRemove);
+ loadBalancerToNodes.addHost(hostToPointToUri, hostToPointToName);
+ log.infov("Reverse proxy will direct requests to {0}", hostToPointToUri);
+ }
+
+ protected void assertSuccessfulLogin(SAMLServlet page, UserRepresentation user, Login loginPage, String expectedString) {
+ page.navigateTo();
+ assertCurrentUrlStartsWith(loginPage);
+ loginPage.form().login(user);
+ WebDriverWait wait = new WebDriverWait(driver, WaitUtils.PAGELOAD_TIMEOUT_MILLIS / 1000);
+ wait.until((WebDriver d) -> d.getPageSource().contains(expectedString));
+ }
+
+ protected void delayedCheckLoggedOut(AbstractPage page, AuthRealm loginPage) {
+ Retry.execute(() -> {
+ try {
+ checkLoggedOut(page, loginPage);
+ } catch (AssertionError | TimeoutException ex) {
+ driver.navigate().refresh();
+ log.debug("[Retriable] Timed out waiting for login page");
+ throw new RuntimeException(ex);
+ }
+ }, 10, 100);
+ }
+
+ protected void checkLoggedOut(AbstractPage page, AuthRealm loginPage) {
+ page.navigateTo();
+ WaitUtils.waitForPageToLoad(driver);
+ assertCurrentUrlStartsWith(loginPage);
+ }
+
+ private String getAppServerId() {
+ Class<?> annotatedClass = getNearestSuperclassWithAnnotation(this.getClass(), AppServerContainer.class);
+
+ return (annotatedClass == null ? "<cannot-find-@AppServerContainer>"
+ : annotatedClass.getAnnotation(AppServerContainer.class).value());
+ }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/keycloak-saml.xml
new file mode 100644
index 0000000..60f48de
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,44 @@
+<!--
+ ~ 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.
+ -->
+
+<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:keycloak:saml:adapter http://www.keycloak.org/schema/keycloak_saml_adapter_1_7.xsd">
+ <SP entityID="http://localhost:8580/employee-distributable/"
+ 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="memberOf"/>
+ <Attribute name="Role"/>
+ </RoleIdentifiers>
+ <IDP entityID="idp">
+ <SingleSignOnService requestBinding="POST"
+ bindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
+ />
+
+ <SingleLogoutService
+ requestBinding="POST"
+ responseBinding="POST"
+ postBindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
+ redirectBindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
+ />
+ </IDP>
+ </SP>
+</keycloak-saml-adapter>
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml-behind-lb.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml-behind-lb.json
new file mode 100644
index 0000000..ae10da2
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml-behind-lb.json
@@ -0,0 +1,164 @@
+{
+ "id": "demo",
+ "realm": "demo",
+ "enabled": true,
+ "sslRequired": "external",
+ "registrationAllowed": true,
+ "resetPasswordAllowed": true,
+ "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
+ "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "requiredCredentials": [ "password" ],
+ "defaultRoles": [ "user" ],
+ "smtpServer": {
+ "from": "auto@keycloak.org",
+ "host": "localhost",
+ "port":"3025"
+ },
+ "users" : [
+ {
+ "username" : "bburke",
+ "enabled": true,
+ "email" : "bburke@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ],
+ "attributes" : {
+ "phone": "617"
+ },
+ "realmRoles": ["manager", "user"],
+ "applicationRoles": {
+ "http://localhost:8580/employee-distributable/": [ "employee" ]
+ }
+ },
+ {
+ "username" : "unauthorized",
+ "enabled": true,
+ "email" : "unauthorized@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ]
+ },
+ {
+ "username" : "topGroupUser",
+ "enabled": true,
+ "email" : "top@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ],
+ "groups": [
+ "/top"
+ ]
+ },
+ {
+ "username" : "level2GroupUser",
+ "enabled": true,
+ "email" : "level2@redhat.com",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "password" }
+ ],
+ "groups": [
+ "/top/level2"
+ ]
+ }
+ ],
+ "clients": [
+ {
+ "clientId": "http://localhost:8580/employee-distributable/",
+ "enabled": true,
+ "protocol": "saml",
+ "fullScopeAllowed": true,
+ "baseUrl": "http://localhost:8580/employee-distributable",
+ "redirectUris": [
+ "http://localhost:8580/employee-distributable/*"
+ ],
+ "attributes": {
+ "saml_assertion_consumer_url_post": "http://localhost:8580/employee-distributable/saml",
+ "saml_assertion_consumer_url_redirect": "http://localhost:8580/employee-distributable/saml",
+ "saml_single_logout_service_url_post": "http://localhost:8580/employee-distributable/saml",
+ "saml_single_logout_service_url_redirect": "http://localhost:8580/employee-distributable/saml",
+ "saml.authnstatement": "true"
+ },
+ "protocolMappers": [
+ {
+ "name": "email",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "email",
+ "friendly.name": "email",
+ "attribute.name": "urn:oid:1.2.840.113549.1.9.1",
+ "attribute.nameformat": "URI Reference"
+ }
+ },
+ {
+ "name": "phone",
+ "protocol": "saml",
+ "protocolMapper": "saml-user-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "phone",
+ "attribute.name": "phone",
+ "attribute.nameformat": "Basic"
+ }
+ },
+ {
+ "name": "role-list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "attribute.name": "Role",
+ "attribute.nameformat": "Basic",
+ "single": "false"
+ }
+ }
+ ]
+ }
+ ],
+ "groups" : [
+ {
+ "name": "top",
+ "attributes": {
+ "topAttribute": ["true"]
+
+ },
+ "realmRoles": ["manager"],
+ "subGroups": [
+ {
+ "name": "level2",
+ "realmRoles": ["user"],
+ "attributes": {
+ "level2Attribute": ["true"]
+
+ }
+ }
+ ]
+ }
+ ],
+
+ "roles" : {
+ "realm" : [
+ {
+ "name": "manager",
+ "description": "Have Manager privileges"
+ },
+ {
+ "name": "user",
+ "description": "Have User privileges"
+ }
+ ],
+ "application" : {
+ "http://localhost:8580/employee-distributable/" : [
+ {
+ "name": "employee",
+ "description": "Have Employee privileges"
+ }
+ ]
+ }
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/common/xslt/arquillian.xsl b/testsuite/integration-arquillian/tests/other/adapters/jboss/common/xslt/arquillian.xsl
index 74541a0..30e7dba 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/jboss/common/xslt/arquillian.xsl
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/common/xslt/arquillian.xsl
@@ -48,6 +48,53 @@
</configuration>
</container>
+ <container qualifier="app-server-${{app.server}}-ha-node-1" mode="manual" >
+ <configuration>
+ <property name="enabled">true</property>
+ <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+ <property name="jbossHome">${app.server.home}</property>
+ <property name="javaHome">${app.server.java.home}</property>
+ <property name="cleanServerBaseDir">${app.server.home}/standalone-ha-node-1</property>
+ <property name="serverConfig">standalone-ha.xml</property>
+ <property name="jbossArguments">
+ -Djboss.socket.binding.port-offset=${app.server.1.port.offset}
+ -Djboss.node.name=ha-node-1
+ ${adapter.test.props}
+ </property>
+ <property name="javaVmArguments">
+ -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7901
+ ${app.server.memory.settings}
+ -Djava.net.preferIPv4Stack=true
+ </property>
+ <property name="managementProtocol">${app.server.management.protocol}</property>
+ <property name="managementPort">${app.server.1.management.port}</property>
+ <property name="startupTimeoutInSeconds">${app.server.startup.timeout}</property>
+ </configuration>
+ </container>
+
+ <container qualifier="app-server-${{app.server}}-ha-node-2" mode="manual" >
+ <configuration>
+ <property name="enabled">true</property>
+ <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
+ <property name="jbossHome">${app.server.home}</property>
+ <property name="javaHome">${app.server.java.home}</property>
+ <property name="cleanServerBaseDir">${app.server.home}/standalone-ha-node-2</property>
+ <property name="serverConfig">standalone-ha.xml</property>
+ <property name="jbossArguments">
+ -Djboss.socket.binding.port-offset=${app.server.2.port.offset}
+ -Djboss.node.name=ha-node-2
+ ${adapter.test.props}
+ </property>
+ <property name="javaVmArguments">
+ -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7902
+ ${app.server.memory.settings}
+ -Djava.net.preferIPv4Stack=true
+ </property>
+ <property name="managementProtocol">${app.server.management.protocol}</property>
+ <property name="managementPort">${app.server.2.management.port}</property>
+ <property name="startupTimeoutInSeconds">${app.server.startup.timeout}</property>
+ </configuration>
+ </container>
</xsl:copy>
</xsl:template>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml
index 7c56a48..35f9501 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml
@@ -30,12 +30,29 @@
<artifactId>integration-arquillian-tests-adapters-eap6</artifactId>
<name>Adapter Tests - JBoss - EAP 6</name>
-
+
+ <dependencies>
+ <dependency>
+ <groupId>org.wildfly.extras.creaper</groupId>
+ <artifactId>creaper-core</artifactId>
+ <scope>test</scope>
+ <version>1.5.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wildfly.core</groupId>
+ <artifactId>wildfly-cli</artifactId>
+ <scope>test</scope>
+ <version>2.2.0.Final</version>
+ </dependency>
+ </dependencies>
+
<properties>
<app.server>eap6</app.server>
<app.server.management.protocol>remote</app.server.management.protocol>
<app.server.management.port>${app.server.management.port.jmx}</app.server.management.port>
+ <app.server.1.management.port>${app.server.1.management.port.jmx}</app.server.1.management.port>
+ <app.server.2.management.port>${app.server.2.management.port.jmx}</app.server.2.management.port>
</properties>
</project>
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/cluster/EAP6SAMLAdapterClusterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/cluster/EAP6SAMLAdapterClusterTest.java
new file mode 100644
index 0000000..f0a166b
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/cluster/EAP6SAMLAdapterClusterTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017 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.
+ */
+package org.keycloak.testsuite.adapter.cluster;
+
+import org.keycloak.testsuite.adapter.page.EmployeeServletDistributable;
+import org.keycloak.testsuite.arquillian.annotation.*;
+
+import java.io.*;
+
+import org.keycloak.testsuite.adapter.servlet.cluster.AbstractSAMLAdapterClusterTest;
+import org.keycloak.testsuite.adapter.servlet.SendUsernameServlet;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.TargetsContainer;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.wildfly.extras.creaper.core.*;
+import org.wildfly.extras.creaper.core.online.*;
+import org.wildfly.extras.creaper.core.online.operations.*;
+
+import static org.keycloak.testsuite.adapter.AbstractServletsAdapterTest.samlServletDeployment;
+
+/**
+ *
+ * @author hmlnarik
+ */
+@AppServerContainer("app-server-eap6")
+public class EAP6SAMLAdapterClusterTest extends AbstractSAMLAdapterClusterTest {
+
+ @TargetsContainer(value = "app-server-eap6-" + NODE_1_NAME)
+ @Deployment(name = EmployeeServletDistributable.DEPLOYMENT_NAME, managed = false)
+ protected static WebArchive employee() {
+ return samlServletDeployment(EmployeeServletDistributable.DEPLOYMENT_NAME, EmployeeServletDistributable.DEPLOYMENT_NAME + "/WEB-INF/web.xml", SendUsernameServlet.class);
+ }
+
+ @TargetsContainer(value = "app-server-eap6-" + NODE_2_NAME)
+ @Deployment(name = EmployeeServletDistributable.DEPLOYMENT_NAME + "_2", managed = false)
+ protected static WebArchive employee2() {
+ return employee();
+ }
+
+ @Override
+ protected void prepareWorkerNode(Integer managementPort) throws IOException, CliException, NumberFormatException {
+ log.infov("Preparing worker node ({0})", managementPort);
+
+ OnlineManagementClient clientWorkerNodeClient = ManagementClient.online(OnlineOptions
+ .standalone()
+ .hostAndPort("localhost", managementPort)
+ .protocol(ManagementProtocol.REMOTE)
+ .build());
+ Operations op = new Operations(clientWorkerNodeClient);
+
+ Batch b = new Batch();
+ Address tcppingStack = Address
+ .subsystem("jgroups")
+ .and("stack", "tcpping");
+ b.add(tcppingStack);
+ b.add(tcppingStack.and("transport", "TRANSPORT"), Values.of("socket-binding", "jgroups-tcp").and("type", "TCP"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "TCPPING"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "initial_hosts"), Values.of("value", "localhost[" + (7600 + PORT_OFFSET_NODE_1) + "],localhost[" + (7600 + PORT_OFFSET_NODE_2) + "]"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "port_range"), Values.of("value", "0"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "num_initial_members"), Values.of("value", "2"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "timeout"), Values.of("value", "3000"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "MERGE2"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "FD_SOCK").and("socket-binding", "jgroups-tcp-fd"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "FD"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "VERIFY_SUSPECT"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "pbcast.NAKACK"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "UNICAST2"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "pbcast.STABLE"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "pbcast.GMS"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "UFC"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "MFC"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "FRAG2"));
+ b.invoke("add-protocol", tcppingStack, Values.of("type", "RSVP"));
+ Assert.assertTrue("Could not add TCPPING JGroups stack", op.batch(b).isSuccess());
+
+ Assert.assertTrue(op.writeAttribute(Address.subsystem("jgroups"), "default-stack", "tcpping").isSuccess());
+ Assert.assertTrue(op.writeAttribute(Address.subsystem("web"), "instance-id", "${jboss.node.name}").isSuccess());
+ Assert.assertTrue(op.add(Address.extension("org.keycloak.keycloak-saml-adapter-subsystem"), Values.of("module", "org.keycloak.keycloak-saml-adapter-subsystem")).isSuccess());
+ Assert.assertTrue(op.add(Address.subsystem("keycloak-saml")).isSuccess());
+
+ clientWorkerNodeClient.execute("reload");
+
+ log.infov("Worker node ({0}) Prepared", managementPort);
+ }
+
+}
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml
new file mode 100644
index 0000000..767eb6c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <distributable/>
+
+ <absolute-ordering/>
+
+ <module-name>%CONTEXT_PATH%</module-name>
+
+ <servlet-mapping>
+ <servlet-name>javax.ws.rs.core.Application</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <error-page>
+ <location>/error.html</location>
+ </error-page>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Application</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>manager</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>KEYCLOAK-SAML</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>manager</role-name>
+ </security-role>
+
+ <context-param>
+ <param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
+ <param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
+ </context-param>
+</web-app>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml
index 885a052..912947f 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml
@@ -30,7 +30,22 @@
<artifactId>integration-arquillian-tests-adapters-wildfly</artifactId>
<name>Adapter Tests - JBoss - Wildfly</name>
-
+
+ <dependencies>
+ <dependency>
+ <groupId>org.wildfly.extras.creaper</groupId>
+ <artifactId>creaper-core</artifactId>
+ <scope>test</scope>
+ <version>1.5.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wildfly.core</groupId>
+ <artifactId>wildfly-cli</artifactId>
+ <scope>test</scope>
+ <version>2.2.0.Final</version>
+ </dependency>
+ </dependencies>
+
<properties>
<app.server>wildfly</app.server>
</properties>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/cluster/WildflySAMLAdapterClusterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/cluster/WildflySAMLAdapterClusterTest.java
new file mode 100644
index 0000000..eb7973c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/cluster/WildflySAMLAdapterClusterTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2017 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.
+ */
+package org.keycloak.testsuite.adapter.cluster;
+
+import org.keycloak.testsuite.adapter.page.EmployeeServletDistributable;
+import org.keycloak.testsuite.arquillian.annotation.*;
+
+import java.io.*;
+
+import org.keycloak.testsuite.adapter.servlet.cluster.AbstractSAMLAdapterClusterTest;
+import org.keycloak.testsuite.adapter.servlet.SendUsernameServlet;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.TargetsContainer;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.wildfly.extras.creaper.core.*;
+import org.wildfly.extras.creaper.core.online.*;
+import org.wildfly.extras.creaper.core.online.operations.*;
+
+import static org.keycloak.testsuite.adapter.AbstractServletsAdapterTest.samlServletDeployment;
+
+/**
+ *
+ * @author hmlnarik
+ */
+@AppServerContainer("app-server-wildfly")
+public class WildflySAMLAdapterClusterTest extends AbstractSAMLAdapterClusterTest {
+
+ @TargetsContainer(value = "app-server-wildfly-" + NODE_1_NAME)
+ @Deployment(name = EmployeeServletDistributable.DEPLOYMENT_NAME, managed = false)
+ protected static WebArchive employee() {
+ return samlServletDeployment(EmployeeServletDistributable.DEPLOYMENT_NAME, EmployeeServletDistributable.DEPLOYMENT_NAME + "/WEB-INF/web.xml", SendUsernameServlet.class);
+ }
+
+ @TargetsContainer(value = "app-server-wildfly-" + NODE_2_NAME)
+ @Deployment(name = EmployeeServletDistributable.DEPLOYMENT_NAME + "_2", managed = false)
+ protected static WebArchive employee2() {
+ return employee();
+ }
+
+ @Override
+ protected void prepareWorkerNode(Integer managementPort) throws IOException, CliException, NumberFormatException {
+ log.infov("Preparing worker node ({0})", managementPort);
+
+ OnlineManagementClient clientWorkerNodeClient = ManagementClient.online(OnlineOptions
+ .standalone()
+ .hostAndPort("localhost", managementPort)
+ .build());
+ Operations op = new Operations(clientWorkerNodeClient);
+
+ Batch b = new Batch();
+ Address tcppingStack = Address
+ .subsystem("jgroups")
+ .and("stack", "tcpping");
+ b.add(tcppingStack);
+ b.add(tcppingStack.and("transport", "TCP"), Values.of("socket-binding", "jgroups-tcp"));
+ b.add(tcppingStack.and("protocol", "TCPPING"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "initial_hosts"), Values.of("value", "localhost[" + (7600 + PORT_OFFSET_NODE_1) + "],localhost[" + (7600 + PORT_OFFSET_NODE_2) + "]"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "port_range"), Values.of("value", "0"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "num_initial_members"), Values.of("value", "2"));
+ b.add(tcppingStack.and("protocol", "TCPPING").and("property", "timeout"), Values.of("value", "3000"));
+ b.add(tcppingStack.and("protocol", "MERGE3"));
+ b.add(tcppingStack.and("protocol", "FD_SOCK"), Values.of("socket-binding", "jgroups-tcp-fd"));
+ b.add(tcppingStack.and("protocol", "FD"));
+ b.add(tcppingStack.and("protocol", "VERIFY_SUSPECT"));
+ b.add(tcppingStack.and("protocol", "pbcast.NAKACK2"));
+ b.add(tcppingStack.and("protocol", "UNICAST3"));
+ b.add(tcppingStack.and("protocol", "pbcast.STABLE"));
+ b.add(tcppingStack.and("protocol", "pbcast.GMS"));
+ b.add(tcppingStack.and("protocol", "MFC"));
+ b.add(tcppingStack.and("protocol", "FRAG2"));
+ b.writeAttribute(Address.subsystem("jgroups").and("channel", "ee"), "stack", "tcpping");
+ op.batch(b);
+
+ op.add(Address.extension("org.keycloak.keycloak-saml-adapter-subsystem"), Values.of("module", "org.keycloak.keycloak-saml-adapter-subsystem"));
+ op.add(Address.subsystem("keycloak-saml"));
+
+ clientWorkerNodeClient.execute("reload");
+
+ log.infov("Worker node ({0}) Prepared", managementPort);
+ }
+
+}
diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml
new file mode 100644
index 0000000..b57928f
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/resources/adapter-test/keycloak-saml/employee-distributable/WEB-INF/web.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <distributable/>
+
+ <absolute-ordering/>
+
+ <module-name>%CONTEXT_PATH%</module-name>
+
+ <servlet-mapping>
+ <servlet-name>javax.ws.rs.core.Application</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <error-page>
+ <location>/error.html</location>
+ </error-page>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Application</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>manager</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>KEYCLOAK-SAML</auth-method>
+ <realm-name>demo</realm-name>
+ </login-config>
+
+ <security-role>
+ <role-name>manager</role-name>
+ </security-role>
+
+ <context-param>
+ <param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
+ <param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
+ </context-param>
+</web-app>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/pom.xml
index 6b63997..624839c 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/pom.xml
@@ -54,6 +54,14 @@
<app.server.ssl.required>false</app.server.ssl.required>
+ <app.server.reverse-proxy.port.offset>500</app.server.reverse-proxy.port.offset>
+ <app.server.1.port.offset>300</app.server.1.port.offset>
+ <app.server.1.management.port>10290</app.server.1.management.port>
+ <app.server.1.management.port.jmx>10299</app.server.1.management.port.jmx>
+ <app.server.2.port.offset>400</app.server.2.port.offset>
+ <app.server.2.management.port>10390</app.server.2.management.port>
+ <app.server.2.management.port.jmx>10399</app.server.2.management.port.jmx>
+
<settings.path></settings.path>
<repo.url></repo.url>
@@ -193,6 +201,14 @@
<app.server.startup.timeout>${app.server.startup.timeout}</app.server.startup.timeout>
<app.server.memory.settings>${app.server.memory.settings}</app.server.memory.settings>
+ <app.server.reverse-proxy.port.offset>${app.server.reverse-proxy.port.offset}</app.server.reverse-proxy.port.offset>
+
+ <app.server.1.port.offset>${app.server.1.port.offset}</app.server.1.port.offset>
+ <app.server.1.management.port>${app.server.1.management.port}</app.server.1.management.port>
+
+ <app.server.2.port.offset>${app.server.2.port.offset}</app.server.2.port.offset>
+ <app.server.2.management.port>${app.server.2.management.port}</app.server.2.management.port>
+
<adapter.test.props>${adapter.test.props}</adapter.test.props>
<adapter.config.bundled>${adapter.config.bundled}</adapter.config.bundled>