keycloak-memoizeit

Changes

Details

diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigPostNoIdpKeyServlet.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigPostNoIdpKeyServlet.java
new file mode 100644
index 0000000..5ef40ae
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigPostNoIdpKeyServlet.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * @author hmlnarik
+ */
+public class EmployeeSigPostNoIdpKeyServlet extends SAMLServlet {
+    public static final String DEPLOYMENT_NAME = "employee-sig-post-noidpkey";
+
+    @ArquillianResource
+    @OperateOnDeployment(DEPLOYMENT_NAME)
+    private URL url;
+
+    @Override
+    public URL getInjectedUrl() {
+        return url;
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigRedirNoIdpKeyServlet.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigRedirNoIdpKeyServlet.java
new file mode 100644
index 0000000..ac6d671
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigRedirNoIdpKeyServlet.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * @author hmlnarik
+ */
+public class EmployeeSigRedirNoIdpKeyServlet extends SAMLServlet {
+    public static final String DEPLOYMENT_NAME = "employee-sig-redir-noidpkey";
+
+    @ArquillianResource
+    @OperateOnDeployment(DEPLOYMENT_NAME)
+    private URL url;
+
+    @Override
+    public URL getInjectedUrl() {
+        return url;
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigRedirOptNoIdpKeyServlet.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigRedirOptNoIdpKeyServlet.java
new file mode 100644
index 0000000..e37c12f
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/EmployeeSigRedirOptNoIdpKeyServlet.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * @author hmlnarik
+ */
+public class EmployeeSigRedirOptNoIdpKeyServlet extends SAMLServlet {
+    public static final String DEPLOYMENT_NAME = "employee-sig-redir-opt-noidpkey";
+
+    @ArquillianResource
+    @OperateOnDeployment(DEPLOYMENT_NAME)
+    private URL url;
+
+    @Override
+    public URL getInjectedUrl() {
+        return url;
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java
index 2906778..6dd3ee3 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLServletsAdapterTest.java
@@ -24,6 +24,12 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.ClientResource;
 import org.keycloak.admin.client.resource.ProtocolMappersResource;
+import org.keycloak.common.util.KeyUtils;
+import org.keycloak.common.util.PemUtils;
+import org.keycloak.keys.Attributes;
+import org.keycloak.keys.KeyProvider;
+import org.keycloak.keys.RsaKeyProviderFactory;
+import org.keycloak.representations.idm.ComponentRepresentation;
 import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
 import org.keycloak.protocol.saml.mappers.RoleListMapper;
 import org.keycloak.representations.idm.ClientRepresentation;
@@ -40,6 +46,9 @@ import org.keycloak.testsuite.adapter.page.BadRealmSalesPostSigServlet;
 import org.keycloak.testsuite.adapter.page.Employee2Servlet;
 import org.keycloak.testsuite.adapter.page.EmployeeServlet;
 import org.keycloak.testsuite.adapter.page.EmployeeSigFrontServlet;
+import org.keycloak.testsuite.adapter.page.EmployeeSigPostNoIdpKeyServlet;
+import org.keycloak.testsuite.adapter.page.EmployeeSigRedirNoIdpKeyServlet;
+import org.keycloak.testsuite.adapter.page.EmployeeSigRedirOptNoIdpKeyServlet;
 import org.keycloak.testsuite.adapter.page.EmployeeSigServlet;
 import org.keycloak.testsuite.adapter.page.InputPortal;
 import org.keycloak.testsuite.adapter.page.MissingAssertionSig;
@@ -80,6 +89,8 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URL;
+import java.security.KeyPair;
+import java.security.PublicKey;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -110,6 +121,15 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
     protected EmployeeSigServlet employeeSigServletPage;
 
     @Page
+    protected EmployeeSigPostNoIdpKeyServlet employeeSigPostNoIdpKeyServletPage;
+
+    @Page
+    protected EmployeeSigRedirNoIdpKeyServlet employeeSigRedirNoIdpKeyServletPage;
+
+    @Page
+    protected EmployeeSigRedirOptNoIdpKeyServlet employeeSigRedirOptNoIdpKeyServletPage;
+
+    @Page
     protected EmployeeSigFrontServlet employeeSigFrontServletPage;
 
     @Page
@@ -184,6 +204,21 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
         return samlServletDeployment(EmployeeSigServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
     }
 
+    @Deployment(name = EmployeeSigPostNoIdpKeyServlet.DEPLOYMENT_NAME)
+    protected static WebArchive employeeSigPostNoIdpKeyServlet() {
+        return samlServletDeployment(EmployeeSigPostNoIdpKeyServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
+    }
+
+    @Deployment(name = EmployeeSigRedirNoIdpKeyServlet.DEPLOYMENT_NAME)
+    protected static WebArchive employeeSigRedirNoIdpKeyServlet() {
+        return samlServletDeployment(EmployeeSigRedirNoIdpKeyServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
+    }
+
+    @Deployment(name = EmployeeSigRedirOptNoIdpKeyServlet.DEPLOYMENT_NAME)
+    protected static WebArchive employeeSigRedirOptNoIdpKeyServlet() {
+        return samlServletDeployment(EmployeeSigRedirOptNoIdpKeyServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
+    }
+
     @Deployment(name = EmployeeSigFrontServlet.DEPLOYMENT_NAME)
     protected static WebArchive employeeSigFront() {
         return samlServletDeployment(EmployeeSigFrontServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
@@ -394,6 +429,69 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
         testSuccessfulAndUnauthorizedLogin(employeeSigServletPage, testRealmSAMLRedirectLoginPage);
     }
 
+    private PublicKey createKeys(String priority) throws Exception {
+        KeyPair keyPair = KeyUtils.generateRsaKeyPair(1024);
+        String privateKeyPem = PemUtils.encodeKey(keyPair.getPrivate());
+        PublicKey publicKey = keyPair.getPublic();
+
+        ComponentRepresentation rep = new ComponentRepresentation();
+        rep.setName("mycomponent");
+        rep.setParentId("demo");
+        rep.setProviderId(RsaKeyProviderFactory.ID);
+        rep.setProviderType(KeyProvider.class.getName());
+
+        org.keycloak.common.util.MultivaluedHashMap config = new org.keycloak.common.util.MultivaluedHashMap();
+        config.addFirst("priority", priority);
+        config.addFirst(Attributes.PRIVATE_KEY_KEY, privateKeyPem);
+        rep.setConfig(config);
+
+        testRealmResource().components().add(rep);
+
+        return publicKey;
+    }
+
+    private void dropKeys(String priority) {
+        for (ComponentRepresentation c : testRealmResource().components().query("demo", KeyProvider.class.getName())) {
+            if (c.getConfig().getFirst("priority").equals(priority)) {
+                testRealmResource().components().component(c.getId()).remove();
+                return;
+            }
+        }
+        throw new RuntimeException("Failed to find keys");
+    }
+
+    private void testRotatedKeysPropagated(SAMLServlet servletPage, Login loginPage) throws Exception {
+        boolean keyDropped = false;
+        try {
+            log.info("Creating new key");
+            createKeys("1000");
+            testSuccessfulAndUnauthorizedLogin(servletPage, loginPage);
+            log.info("Dropping new key");
+            dropKeys("1000");
+            keyDropped = true;
+            testSuccessfulAndUnauthorizedLogin(servletPage, loginPage);
+        } finally {
+            if (! keyDropped) {
+                dropKeys("1000");
+            }
+        }
+    }
+
+    @Test
+    public void employeeSigPostNoIdpKeyTest() throws Exception {
+        testRotatedKeysPropagated(employeeSigPostNoIdpKeyServletPage, testRealmSAMLPostLoginPage);
+    }
+
+    @Test
+    public void employeeSigRedirNoIdpKeyTest() throws Exception {
+        testRotatedKeysPropagated(employeeSigRedirNoIdpKeyServletPage, testRealmSAMLRedirectLoginPage);
+    }
+
+    @Test
+    public void employeeSigRedirOptNoIdpKeyTest() throws Exception {
+        testRotatedKeysPropagated(employeeSigRedirOptNoIdpKeyServletPage, testRealmSAMLRedirectLoginPage);
+    }
+
     @Test
     public void employeeSigFrontTest() {
         testSuccessfulAndUnauthorizedLogin(employeeSigFrontServletPage, testRealmSAMLRedirectLoginPage);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java
index 626c0d4..4328c8f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java
@@ -21,13 +21,11 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.admin.ApiUtil;
 import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.Matchers.*;
 
 /**
  * Test getting the installation/configuration files for OIDC and SAML.
@@ -71,7 +69,7 @@ public class InstallationTest extends AbstractClientTest {
     public void testOidcJBossXml() {
         String xml = oidcClient.getInstallationProvider("keycloak-oidc-jboss-subsystem");
         assertOidcInstallationConfig(xml);
-        assertTrue(xml.contains("<secure-deployment"));
+        assertThat(xml, containsString("<secure-deployment"));
     }
 
     @Test
@@ -81,43 +79,43 @@ public class InstallationTest extends AbstractClientTest {
     }
 
     private void assertOidcInstallationConfig(String config) {
-        assertTrue(config.contains("master"));
-        assertFalse(config.contains(ApiUtil.findActiveKey(testRealmResource()).getPublicKey()));
-        assertTrue(config.contains(authServerUrl()));
+        assertThat(config, containsString("master"));
+        assertThat(config, not(containsString(ApiUtil.findActiveKey(testRealmResource()).getPublicKey())));
+        assertThat(config, containsString(authServerUrl()));
     }
 
     @Test
     public void testSamlMetadataIdpDescriptor() {
         String xml = samlClient.getInstallationProvider("saml-idp-descriptor");
-        assertTrue(xml.contains("<EntityDescriptor"));
-        assertTrue(xml.contains("<IDPSSODescriptor"));
-        assertTrue(xml.contains(ApiUtil.findActiveKey(testRealmResource()).getCertificate()));
-        assertTrue(xml.contains(samlUrl()));
+        assertThat(xml, containsString("<EntityDescriptor"));
+        assertThat(xml, containsString("<IDPSSODescriptor"));
+        assertThat(xml, containsString(ApiUtil.findActiveKey(testRealmResource()).getCertificate()));
+        assertThat(xml, containsString(samlUrl()));
     }
 
     @Test
     public void testSamlAdapterXml() {
         String xml = samlClient.getInstallationProvider("keycloak-saml");
-        assertTrue(xml.contains("<keycloak-saml-adapter>"));
-        assertTrue(xml.contains(SAML_NAME));
-        assertTrue(xml.contains(ApiUtil.findActiveKey(testRealmResource()).getCertificate()));
-        assertTrue(xml.contains(samlUrl()));
+        assertThat(xml, containsString("<keycloak-saml-adapter>"));
+        assertThat(xml, containsString(SAML_NAME));
+        assertThat(xml, not(containsString(ApiUtil.findActiveKey(testRealmResource()).getCertificate())));
+        assertThat(xml, containsString(samlUrl()));
     }
 
     @Test
     public void testSamlMetadataSpDescriptor() {
         String xml = samlClient.getInstallationProvider("saml-sp-descriptor");
-        assertTrue(xml.contains("<EntityDescriptor"));
-        assertTrue(xml.contains("<SPSSODescriptor"));
-        assertTrue(xml.contains(SAML_NAME));
+        assertThat(xml, containsString("<EntityDescriptor"));
+        assertThat(xml, containsString("<SPSSODescriptor"));
+        assertThat(xml, containsString(SAML_NAME));
     }
 
     @Test
     public void testSamlJBossXml() {
         String xml = samlClient.getInstallationProvider("keycloak-saml-subsystem");
-        assertTrue(xml.contains("<secure-deployment"));
-        assertTrue(xml.contains(SAML_NAME));
-        assertTrue(xml.contains(ApiUtil.findActiveKey(testRealmResource()).getCertificate()));
-        assertTrue(xml.contains(samlUrl()));
+        assertThat(xml, containsString("<secure-deployment"));
+        assertThat(xml, containsString(SAML_NAME));
+        assertThat(xml, not(containsString(ApiUtil.findActiveKey(testRealmResource()).getCertificate())));
+        assertThat(xml, containsString(samlUrl()));
     }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-post-noidpkey/WEB-INF/keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-post-noidpkey/WEB-INF/keycloak-saml.xml
new file mode 100644
index 0000000..acd3d9d
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-post-noidpkey/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,54 @@
+<!--
+  ~ 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>
+    <SP entityID="http://localhost:8081/employee-sig-post-noidpkey/"
+        sslPolicy="EXTERNAL"
+        logoutPage="/logout.jsp"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        forceAuthentication="false">
+        <Keys>
+            <Key signing="true" >
+                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                    <PrivateKey alias="http://localhost:8080/employee-sig/" password="test123"/>
+                    <Certificate alias="http://localhost:8080/employee-sig/"/>
+                </KeyStore>
+            </Key>
+        </Keys>
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp">
+            <SingleSignOnService signRequest="true"
+                                 validateResponseSignature="true"
+                                 requestBinding="POST"
+                                 bindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
+                    />
+
+            <SingleLogoutService
+                    validateRequestSignature="true"
+                    validateResponseSignature="true"
+                    signRequest="true"
+                    signResponse="true"
+                    requestBinding="POST"
+                    responseBinding="POST"
+                    postBindingUrl="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/employee-sig-post-noidpkey/WEB-INF/keystore.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-post-noidpkey/WEB-INF/keystore.jks
new file mode 100644
index 0000000..4daad21
Binary files /dev/null and b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-post-noidpkey/WEB-INF/keystore.jks differ
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-noidpkey/WEB-INF/keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-noidpkey/WEB-INF/keycloak-saml.xml
new file mode 100644
index 0000000..c134693
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-noidpkey/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,54 @@
+<!--
+  ~ 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>
+    <SP entityID="http://localhost:8081/employee-sig-redir-noidpkey/"
+        sslPolicy="EXTERNAL"
+        logoutPage="/logout.jsp"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        forceAuthentication="false">
+        <Keys>
+            <Key signing="true" >
+                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                    <PrivateKey alias="http://localhost:8080/employee-sig/" password="test123"/>
+                    <Certificate alias="http://localhost:8080/employee-sig/"/>
+                </KeyStore>
+            </Key>
+        </Keys>
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp">
+            <SingleSignOnService signRequest="true"
+                                 validateResponseSignature="true"
+                                 requestBinding="REDIRECT"
+                                 bindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
+                    />
+
+            <SingleLogoutService
+                    validateRequestSignature="true"
+                    validateResponseSignature="true"
+                    signRequest="true"
+                    signResponse="true"
+                    requestBinding="REDIRECT"
+                    responseBinding="REDIRECT"
+                    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/employee-sig-redir-noidpkey/WEB-INF/keystore.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-noidpkey/WEB-INF/keystore.jks
new file mode 100644
index 0000000..4daad21
Binary files /dev/null and b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-noidpkey/WEB-INF/keystore.jks differ
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-opt-noidpkey/WEB-INF/keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-opt-noidpkey/WEB-INF/keycloak-saml.xml
new file mode 100644
index 0000000..8df82ae
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-opt-noidpkey/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,54 @@
+<!--
+  ~ 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>
+    <SP entityID="http://localhost:8081/employee-sig-redir-opt-noidpkey/"
+        sslPolicy="EXTERNAL"
+        logoutPage="/logout.jsp"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        forceAuthentication="false">
+        <Keys>
+            <Key signing="true" >
+                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                    <PrivateKey alias="http://localhost:8080/employee-sig/" password="test123"/>
+                    <Certificate alias="http://localhost:8080/employee-sig/"/>
+                </KeyStore>
+            </Key>
+        </Keys>
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp">
+            <SingleSignOnService signRequest="true"
+                                 validateResponseSignature="true"
+                                 requestBinding="REDIRECT"
+                                 bindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
+                    />
+
+            <SingleLogoutService
+                    validateRequestSignature="true"
+                    validateResponseSignature="true"
+                    signRequest="true"
+                    signResponse="true"
+                    requestBinding="REDIRECT"
+                    responseBinding="REDIRECT"
+                    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/employee-sig-redir-opt-noidpkey/WEB-INF/keystore.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-opt-noidpkey/WEB-INF/keystore.jks
new file mode 100644
index 0000000..4daad21
Binary files /dev/null and b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/employee-sig-redir-opt-noidpkey/WEB-INF/keystore.jks differ
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json
index 0e25d89..cca23fc 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/testsaml.json
@@ -334,6 +334,61 @@
             }
         },
         {
+            "clientId": "http://localhost:8081/employee-sig-redir-noidpkey/",
+            "enabled": true,
+            "protocol": "saml",
+            "fullScopeAllowed": true,
+            "baseUrl": "http://localhost:8080/employee-sig-redir-noidpkey",
+            "redirectUris": [
+                "http://localhost:8080/employee-sig-redir-noidpkey/*"
+            ],
+            "adminUrl": "http://localhost:8080/employee-sig-redir-noidpkey",
+            "attributes": {
+                "saml.server.signature": "true",
+                "saml.client.signature": "true",
+                "saml.signature.algorithm": "RSA_SHA256",
+                "saml.authnstatement": "true",
+                "saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
+            }
+        },
+        {
+            "clientId": "http://localhost:8081/employee-sig-redir-opt-noidpkey/",
+            "enabled": true,
+            "protocol": "saml",
+            "fullScopeAllowed": true,
+            "baseUrl": "http://localhost:8080/employee-sig-redir-opt-noidpkey",
+            "redirectUris": [
+                "http://localhost:8080/employee-sig-redir-opt-noidpkey/*"
+            ],
+            "adminUrl": "http://localhost:8080/employee-sig-redir-opt-noidpkey",
+            "attributes": {
+                "saml.server.signature": "true",
+                "saml.server.signature.keyinfo.ext": "true",
+                "saml.client.signature": "true",
+                "saml.signature.algorithm": "RSA_SHA256",
+                "saml.authnstatement": "true",
+                "saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
+            }
+        },
+        {
+            "clientId": "http://localhost:8081/employee-sig-post-noidpkey/",
+            "enabled": true,
+            "protocol": "saml",
+            "fullScopeAllowed": true,
+            "baseUrl": "http://localhost:8080/employee-sig-post-noidpkey",
+            "redirectUris": [
+                "http://localhost:8080/employee-sig-post-noidpkey/*"
+            ],
+            "adminUrl": "http://localhost:8080/employee-sig-post-noidpkey",
+            "attributes": {
+                "saml.server.signature": "true",
+                "saml.client.signature": "true",
+                "saml.signature.algorithm": "RSA_SHA256",
+                "saml.authnstatement": "true",
+                "saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp"
+            }
+        },
+        {
             "clientId": "http://localhost:8081/employee/",
             "enabled": true,
             "protocol": "saml",