KEYCLOAK-4897 Tests for assertion-only signatures with encrypted assertions
This commit is contained in:
parent
71f0db0837
commit
10c9e0f00f
9 changed files with 265 additions and 4 deletions
|
@ -27,6 +27,7 @@ import java.net.URL;
|
|||
*/
|
||||
public class SalesPostEncServlet extends SAMLServlet {
|
||||
public static final String DEPLOYMENT_NAME = "sales-post-enc";
|
||||
public static final String CLIENT_NAME = "http://localhost:8081/sales-post-enc/";
|
||||
|
||||
@ArquillianResource
|
||||
@OperateOnDeployment(DEPLOYMENT_NAME)
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 mhajas
|
||||
*/
|
||||
public class SalesPostEncSignAssertionsOnlyServlet extends SAMLServlet {
|
||||
public static final String DEPLOYMENT_NAME = "sales-post-enc-sign-assertions-only";
|
||||
public static final String CLIENT_NAME = "http://localhost:8081/sales-post-enc-sign-assertions-only/";
|
||||
|
||||
@ArquillianResource
|
||||
@OperateOnDeployment(DEPLOYMENT_NAME)
|
||||
private URL url;
|
||||
|
||||
@Override
|
||||
public URL getInjectedUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.keycloak.testsuite.util;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import java.io.Closeable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class ClientAttributeUpdater {
|
||||
|
||||
private final Map<String, String> originalAttributes = new HashMap<>();
|
||||
|
||||
private final ClientResource clientResource;
|
||||
|
||||
private final ClientRepresentation rep;
|
||||
|
||||
public ClientAttributeUpdater(ClientResource clientResource) {
|
||||
this.clientResource = clientResource;
|
||||
this.rep = clientResource.toRepresentation();
|
||||
if (this.rep.getAttributes() == null) {
|
||||
this.rep.setAttributes(new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
public ClientAttributeUpdater setAttribute(String name, String value) {
|
||||
if (! originalAttributes.containsKey(name)) {
|
||||
this.originalAttributes.put(name, this.rep.getAttributes().put(name, value));
|
||||
} else {
|
||||
this.rep.getAttributes().put(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientAttributeUpdater removeAttribute(String name) {
|
||||
if (! originalAttributes.containsKey(name)) {
|
||||
this.originalAttributes.put(name, this.rep.getAttributes().put(name, null));
|
||||
} else {
|
||||
this.rep.getAttributes().put(name, null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Closeable update() {
|
||||
clientResource.update(rep);
|
||||
|
||||
return () -> {
|
||||
rep.getAttributes().putAll(originalAttributes);
|
||||
clientResource.update(rep);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.keycloak.testsuite.util;
|
||||
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import java.io.Closeable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class RealmAttributeUpdater {
|
||||
|
||||
private final Map<String, String> originalAttributes = new HashMap<>();
|
||||
|
||||
private final RealmResource realmResource;
|
||||
|
||||
private final RealmRepresentation rep;
|
||||
|
||||
public RealmAttributeUpdater(RealmResource realmResource) {
|
||||
this.realmResource = realmResource;
|
||||
this.rep = realmResource.toRepresentation();
|
||||
if (this.rep.getAttributes() == null) {
|
||||
this.rep.setAttributes(new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
public RealmAttributeUpdater setAttribute(String name, String value) {
|
||||
if (! originalAttributes.containsKey(name)) {
|
||||
this.originalAttributes.put(name, this.rep.getAttributes().put(name, value));
|
||||
} else {
|
||||
this.rep.getAttributes().put(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RealmAttributeUpdater removeAttribute(String name) {
|
||||
if (! originalAttributes.containsKey(name)) {
|
||||
this.originalAttributes.put(name, this.rep.getAttributes().put(name, null));
|
||||
} else {
|
||||
this.rep.getAttributes().put(name, null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Closeable update() {
|
||||
realmResource.update(rep);
|
||||
|
||||
return () -> {
|
||||
rep.getAttributes().putAll(originalAttributes);
|
||||
realmResource.update(rep);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLS
|
|||
salesMetadataServletPage.checkRoles(true);
|
||||
salesPostServletPage.checkRoles(true);
|
||||
salesPostEncServletPage.checkRoles(true);
|
||||
salesPostEncSignAssertionsOnlyServletPage.checkRoles(true);
|
||||
salesPostSigServletPage.checkRoles(true);
|
||||
salesPostPassiveServletPage.checkRoles(true);
|
||||
salesPostSigPersistentServletPage.checkRoles(true);
|
||||
|
@ -56,6 +57,7 @@ public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLS
|
|||
salesMetadataServletPage.checkRoles(false);
|
||||
salesPostServletPage.checkRoles(false);
|
||||
salesPostEncServletPage.checkRoles(false);
|
||||
salesPostEncSignAssertionsOnlyServletPage.checkRoles(false);
|
||||
salesPostSigServletPage.checkRoles(false);
|
||||
salesPostPassiveServletPage.checkRoles(false);
|
||||
salesPostSigEmailServletPage.checkRoles(false);
|
||||
|
|
|
@ -86,14 +86,13 @@ import javax.xml.validation.Schema;
|
|||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.Closeable;
|
||||
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;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
@ -107,7 +106,6 @@ 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.Binding.POST;
|
||||
import static org.keycloak.testsuite.util.SamlClient.idpInitiatedLogin;
|
||||
import static org.keycloak.testsuite.util.SamlClient.login;
|
||||
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
|
||||
|
@ -156,6 +154,9 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
|||
@Page
|
||||
protected SalesPostEncServlet salesPostEncServletPage;
|
||||
|
||||
@Page
|
||||
protected SalesPostEncSignAssertionsOnlyServlet salesPostEncSignAssertionsOnlyServletPage;
|
||||
|
||||
@Page
|
||||
protected SalesPostPassiveServlet salesPostPassiveServletPage;
|
||||
|
||||
|
@ -259,6 +260,11 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
|||
return samlServletDeployment(SalesPostEncServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
|
||||
}
|
||||
|
||||
@Deployment(name = SalesPostEncSignAssertionsOnlyServlet.DEPLOYMENT_NAME)
|
||||
protected static WebArchive salesPostEncSignAssertionsOnly() {
|
||||
return samlServletDeployment(SalesPostEncSignAssertionsOnlyServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
|
||||
}
|
||||
|
||||
@Deployment(name = SalesPostPassiveServlet.DEPLOYMENT_NAME)
|
||||
protected static WebArchive salesPostPassive() {
|
||||
return samlServletDeployment(SalesPostPassiveServlet.DEPLOYMENT_NAME, SendUsernameServlet.class);
|
||||
|
@ -625,6 +631,24 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
|||
testSuccessfulAndUnauthorizedLogin(salesPostEncServletPage, testRealmSAMLPostLoginPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void salesPostEncSignedAssertionsOnlyTest() throws Exception {
|
||||
testSuccessfulAndUnauthorizedLogin(salesPostEncSignAssertionsOnlyServletPage, testRealmSAMLPostLoginPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void salesPostEncSignedAssertionsAndDocumentTest() throws Exception {
|
||||
ClientRepresentation salesPostEncClient = testRealmResource().clients().findByClientId(SalesPostEncServlet.CLIENT_NAME).get(0);
|
||||
try (Closeable client = new ClientAttributeUpdater(testRealmResource().clients().get(salesPostEncClient.getId()))
|
||||
.setAttribute(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, "true")
|
||||
.setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "true")
|
||||
.update()) {
|
||||
testSuccessfulAndUnauthorizedLogin(salesPostEncServletPage, testRealmSAMLPostLoginPage);
|
||||
} finally {
|
||||
salesPostEncServletPage.logout();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void salesPostPassiveTest() {
|
||||
salesPostPassiveServletPage.navigateTo();
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<!--
|
||||
~ 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:8081/sales-post-enc-sign-assertions-only/"
|
||||
sslPolicy="EXTERNAL"
|
||||
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
|
||||
logoutPage="/logout.jsp"
|
||||
forceAuthentication="false">
|
||||
<Keys>
|
||||
<Key signing="true" encryption="true">
|
||||
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
|
||||
<PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
|
||||
<Certificate alias="http://localhost:8080/sales-post-enc/"/>
|
||||
</KeyStore>
|
||||
</Key>
|
||||
</Keys>
|
||||
<PrincipalNameMapping policy="FROM_NAME_ID"/>
|
||||
<RoleIdentifiers>
|
||||
<Attribute name="Role"/>
|
||||
</RoleIdentifiers>
|
||||
<IDP entityID="idp">
|
||||
<SingleSignOnService signRequest="true"
|
||||
validateResponseSignature="false"
|
||||
validateAssertionSignature="true"
|
||||
requestBinding="POST"
|
||||
bindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
|
||||
/>
|
||||
|
||||
<SingleLogoutService
|
||||
validateRequestSignature="true"
|
||||
validateResponseSignature="false"
|
||||
signRequest="true"
|
||||
signResponse="true"
|
||||
requestBinding="POST"
|
||||
responseBinding="POST"
|
||||
postBindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
|
||||
redirectBindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
|
||||
/>
|
||||
<Keys>
|
||||
<Key signing="true" >
|
||||
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
|
||||
<Certificate alias="demo"/>
|
||||
</KeyStore>
|
||||
</Key>
|
||||
</Keys>
|
||||
</IDP>
|
||||
</SP>
|
||||
</keycloak-saml-adapter>
|
Binary file not shown.
|
@ -331,6 +331,25 @@
|
|||
"saml.encryption.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g=="
|
||||
}
|
||||
},
|
||||
{
|
||||
"clientId": "http://localhost:8081/sales-post-enc-sign-assertions-only/",
|
||||
"enabled": true,
|
||||
"protocol": "saml",
|
||||
"fullScopeAllowed": true,
|
||||
"baseUrl": "http://localhost:8080/sales-post-enc-sign-assertions-only",
|
||||
"redirectUris": [
|
||||
],
|
||||
"attributes": {
|
||||
"saml.server.signature": "false",
|
||||
"saml.assertion.signature": "true",
|
||||
"saml.signature.algorithm": "RSA_SHA512",
|
||||
"saml.client.signature": "true",
|
||||
"saml.encrypt": "true",
|
||||
"saml.authnstatement": "true",
|
||||
"saml.signing.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g==",
|
||||
"saml.encryption.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g=="
|
||||
}
|
||||
},
|
||||
{
|
||||
"clientId": "http://localhost:8081/employee-sig/",
|
||||
"enabled": true,
|
||||
|
|
Loading…
Reference in a new issue