keycloak-uncached

Details

diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
index 5bdea6e..f11ac07 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/IOUtil.java
@@ -227,6 +227,27 @@ public class IOUtil {
         currentElement.appendChild(node);
     }
 
+    public static void removeElementFromDoc(Document doc, String path) {
+        String[] pathSegments = path.split("/");
+
+        Element currentElement = (Element) doc.getElementsByTagName(pathSegments[0]).item(0);
+        if (currentElement == null) {
+            log.warn("Not able to find element: " + pathSegments[0] + " in document");
+            return;
+        }
+
+        for (int i = 1; i < pathSegments.length; i++) {
+            currentElement = (Element) currentElement.getElementsByTagName(pathSegments[i]).item(0);
+
+            if (currentElement == null) {
+                log.warn("Not able to find element: " + pathSegments[i] + " in " + pathSegments[i - 1]);
+                return;
+            }
+        }
+
+        currentElement.getParentNode().removeChild(currentElement);
+    }
+
     public static void execCommand(String command, File dir) throws IOException, InterruptedException {
         Process process = Runtime.getRuntime().exec(command, null, dir);
         if (process.waitFor(10, TimeUnit.SECONDS)) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLFilterServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLFilterServletAdapterTest.java
index ae64a74..d89fe67 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLFilterServletAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractSAMLFilterServletAdapterTest.java
@@ -25,7 +25,6 @@ public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLS
         salesPostEncServletPage.checkRoles(true);
         salesPostSigServletPage.checkRoles(true);
         salesPostPassiveServletPage.checkRoles(true);
-        salesPostSigEmailServletPage.checkRoles(true);
         salesPostSigPersistentServletPage.checkRoles(true);
         salesPostSigTransientServletPage.checkRoles(true);
         salesPostAssertionAndResponseSigPage.checkRoles(true);
@@ -38,6 +37,11 @@ public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLS
         testRealmLoginPage.form().login(bburkeUser);
         employee2ServletPage.checkRolesEndPoint(true);
         employee2ServletPage.logout();
+
+        salesPostSigEmailServletPage.navigateTo();
+        testRealmLoginPage.form().login(bburkeUser);
+        salesPostSigEmailServletPage.checkRolesEndPoint(true);
+        salesPostSigEmailServletPage.logout();
     }
 
     @After
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 e728eaa..28fd3e1 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
@@ -130,6 +130,7 @@ import static org.keycloak.testsuite.util.IOUtil.loadXML;
 import static org.keycloak.testsuite.util.IOUtil.modifyDocElementAttribute;
 import static org.keycloak.testsuite.util.Matchers.bodyHC;
 import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC;
+import static org.keycloak.testsuite.util.SamlClient.idpInitiatedLogin;
 import static org.keycloak.testsuite.util.SamlClient.login;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
 import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
@@ -734,7 +735,7 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
     }
 
     @Test
-    public void idpInitiatedLogin() {
+    public void idpInitiatedLoginTest() {
         samlidpInitiatedLoginPage.setAuthRealm(SAMLSERVLETDEMO);
         samlidpInitiatedLoginPage.setUrlName("employee2");
         samlidpInitiatedLoginPage.navigateTo();
@@ -1027,6 +1028,47 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
         }
     }
 
+    // KEYCLOAK-4329
+    @Test
+    public void testEmptyKeyInfoElement() {
+        samlidpInitiatedLoginPage.setAuthRealm(SAMLSERVLETDEMO);
+        samlidpInitiatedLoginPage.setUrlName("sales-post-sig-email");
+        System.out.println(samlidpInitiatedLoginPage.toString());
+        URI idpInitiatedLoginPage = URI.create(samlidpInitiatedLoginPage.toString());
+
+        log.debug("Log in using idp initiated login");
+        SAMLDocumentHolder documentHolder = idpInitiatedLogin(bburkeUser, idpInitiatedLoginPage, SamlClient.Binding.POST);
+
+
+        log.debug("Removing KeyInfo from Keycloak response");
+        Document responseDoc = documentHolder.getSamlDocument();
+        IOUtil.removeElementFromDoc(responseDoc, "samlp:Response/dsig:Signature/dsig:KeyInfo");
+
+        CloseableHttpResponse response = null;
+        try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+            HttpClientContext context = HttpClientContext.create();
+
+            log.debug("Sending response to SP");
+            HttpUriRequest post = SamlClient.Binding.POST.createSamlPostUnsignedRequest(getAppServerSamlEndpoint(salesPostSigEmailServletPage), null, responseDoc);
+            response = client.execute(post, context);
+            System.out.println(EntityUtils.toString(response.getEntity()));
+            assertThat(response, statusCodeIsHC(Response.Status.FOUND));
+            response.close();
+
+            HttpGet get = new HttpGet(salesPostSigEmailServletPage.toString());
+            response = client.execute(get);
+            assertThat(response, statusCodeIsHC(Response.Status.OK));
+            assertThat(response, bodyHC(containsString("principal=bburke")));
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        } finally {
+            if (response != null) {
+                EntityUtils.consumeQuietly(response.getEntity());
+                try { response.close(); } catch (IOException ex) { }
+            }
+        }
+    }
+
     private URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException {
         return RealmsResource
                 .protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SamlClient.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SamlClient.java
index f4066f6..8a27896 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SamlClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SamlClient.java
@@ -348,4 +348,43 @@ public class SamlClient {
         }
     }
 
+    /**
+     * Send request for login form and then login using user param
+     * @param user
+     * @param idpInitiatedURI
+     * @param expectedResponseBinding
+     * @return
+     */
+    public static SAMLDocumentHolder idpInitiatedLogin(UserRepresentation user, URI idpInitiatedURI, Binding expectedResponseBinding) {
+        CloseableHttpResponse response = null;
+        SamlClient.RedirectStrategyWithSwitchableFollowRedirect strategy = new SamlClient.RedirectStrategyWithSwitchableFollowRedirect();
+        try (CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(strategy).build()) {
+
+            HttpGet get = new HttpGet(idpInitiatedURI);
+            response = client.execute(get);
+            assertThat(response, statusCodeIsHC(Response.Status.OK));
+
+            HttpClientContext context = HttpClientContext.create();
+
+            String loginPageText = EntityUtils.toString(response.getEntity(), "UTF-8");
+            response.close();
+
+            assertThat(loginPageText, containsString("login"));
+
+            HttpUriRequest loginRequest = handleLoginPage(user, loginPageText);
+
+            strategy.setRedirectable(false);
+            response = client.execute(loginRequest, context);
+
+            return expectedResponseBinding.extractResponse(response);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        } finally {
+            if (response != null) {
+                EntityUtils.consumeQuietly(response.getEntity());
+                try { response.close(); } catch (IOException ex) { }
+            }
+        }
+    }
+
 }
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 cca23fc..6bed985 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
@@ -259,6 +259,7 @@
                 "saml.signature.algorithm": "RSA_SHA256",
                 "saml.client.signature": "true",
                 "saml.authnstatement": "true",
+                "saml_idp_initiated_sso_url_name" : "sales-post-sig-email",
                 "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
             }
         },