KEYCLOAK-4329 Add test for empty KeyInfo
This commit is contained in:
parent
d72b67c460
commit
91bcc24977
5 changed files with 109 additions and 2 deletions
|
@ -227,6 +227,27 @@ public class IOUtil {
|
||||||
currentElement.appendChild(node);
|
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 {
|
public static void execCommand(String command, File dir) throws IOException, InterruptedException {
|
||||||
Process process = Runtime.getRuntime().exec(command, null, dir);
|
Process process = Runtime.getRuntime().exec(command, null, dir);
|
||||||
if (process.waitFor(10, TimeUnit.SECONDS)) {
|
if (process.waitFor(10, TimeUnit.SECONDS)) {
|
||||||
|
|
|
@ -25,7 +25,6 @@ public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLS
|
||||||
salesPostEncServletPage.checkRoles(true);
|
salesPostEncServletPage.checkRoles(true);
|
||||||
salesPostSigServletPage.checkRoles(true);
|
salesPostSigServletPage.checkRoles(true);
|
||||||
salesPostPassiveServletPage.checkRoles(true);
|
salesPostPassiveServletPage.checkRoles(true);
|
||||||
salesPostSigEmailServletPage.checkRoles(true);
|
|
||||||
salesPostSigPersistentServletPage.checkRoles(true);
|
salesPostSigPersistentServletPage.checkRoles(true);
|
||||||
salesPostSigTransientServletPage.checkRoles(true);
|
salesPostSigTransientServletPage.checkRoles(true);
|
||||||
salesPostAssertionAndResponseSigPage.checkRoles(true);
|
salesPostAssertionAndResponseSigPage.checkRoles(true);
|
||||||
|
@ -38,6 +37,11 @@ public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLS
|
||||||
testRealmLoginPage.form().login(bburkeUser);
|
testRealmLoginPage.form().login(bburkeUser);
|
||||||
employee2ServletPage.checkRolesEndPoint(true);
|
employee2ServletPage.checkRolesEndPoint(true);
|
||||||
employee2ServletPage.logout();
|
employee2ServletPage.logout();
|
||||||
|
|
||||||
|
salesPostSigEmailServletPage.navigateTo();
|
||||||
|
testRealmLoginPage.form().login(bburkeUser);
|
||||||
|
salesPostSigEmailServletPage.checkRolesEndPoint(true);
|
||||||
|
salesPostSigEmailServletPage.logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -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.IOUtil.modifyDocElementAttribute;
|
||||||
import static org.keycloak.testsuite.util.Matchers.bodyHC;
|
import static org.keycloak.testsuite.util.Matchers.bodyHC;
|
||||||
import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC;
|
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.SamlClient.login;
|
||||||
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
|
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
|
||||||
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
||||||
|
@ -734,7 +735,7 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void idpInitiatedLogin() {
|
public void idpInitiatedLoginTest() {
|
||||||
samlidpInitiatedLoginPage.setAuthRealm(SAMLSERVLETDEMO);
|
samlidpInitiatedLoginPage.setAuthRealm(SAMLSERVLETDEMO);
|
||||||
samlidpInitiatedLoginPage.setUrlName("employee2");
|
samlidpInitiatedLoginPage.setUrlName("employee2");
|
||||||
samlidpInitiatedLoginPage.navigateTo();
|
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 {
|
private URI getAuthServerSamlEndpoint(String realm) throws IllegalArgumentException, UriBuilderException {
|
||||||
return RealmsResource
|
return RealmsResource
|
||||||
.protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
|
.protocolUrl(UriBuilder.fromUri(getAuthServerRoot()))
|
||||||
|
|
|
@ -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) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,6 +259,7 @@
|
||||||
"saml.signature.algorithm": "RSA_SHA256",
|
"saml.signature.algorithm": "RSA_SHA256",
|
||||||
"saml.client.signature": "true",
|
"saml.client.signature": "true",
|
||||||
"saml.authnstatement": "true",
|
"saml.authnstatement": "true",
|
||||||
|
"saml_idp_initiated_sso_url_name" : "sales-post-sig-email",
|
||||||
"saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
|
"saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue