KEYCLOAK-4377
This commit is contained in:
1 parent
1c10199698
commit
a3ccac2012
12 files changed
+233
-82
No files matched your search
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.testsuite.util;
|
||||
package org.keycloak.testsuite.updaters;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package org.keycloak.testsuite.updaters;
|
||||
|
||||
import org.keycloak.admin.client.resource.IdentityProviderResource;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import java.io.Closeable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class IdentityProviderAttributeUpdater {
|
||||
|
||||
private final Map<String, String> originalAttributes = new HashMap<>();
|
||||
|
||||
private final IdentityProviderResource identityProviderResource;
|
||||
|
||||
private final IdentityProviderRepresentation rep;
|
||||
|
||||
public IdentityProviderAttributeUpdater(IdentityProviderResource identityProviderResource) {
|
||||
this.identityProviderResource = identityProviderResource;
|
||||
this.rep = identityProviderResource.toRepresentation();
|
||||
if (this.rep.getConfig() == null) {
|
||||
this.rep.setConfig(new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
public IdentityProviderAttributeUpdater setAttribute(String name, String value) {
|
||||
if (! originalAttributes.containsKey(name)) {
|
||||
this.originalAttributes.put(name, this.rep.getConfig().put(name, value));
|
||||
} else {
|
||||
this.rep.getConfig().put(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public IdentityProviderAttributeUpdater removeAttribute(String name) {
|
||||
if (! originalAttributes.containsKey(name)) {
|
||||
this.originalAttributes.put(name, this.rep.getConfig().put(name, null));
|
||||
} else {
|
||||
this.rep.getConfig().put(name, null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Closeable update() {
|
||||
identityProviderResource.update(rep);
|
||||
|
||||
return () -> {
|
||||
rep.getConfig().putAll(originalAttributes);
|
||||
identityProviderResource.update(rep);
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.keycloak.testsuite.util;
|
||||
package org.keycloak.testsuite.updaters;
|
||||
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.util;
|
||||
package org.keycloak.testsuite.updaters;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.keycloak.testsuite.adapter.servlet;
|
||||
|
||||
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
|
||||
+16
-11
@@ -1,6 +1,5 @@
|
||||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -14,7 +13,6 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.pages.ConsentPage;
|
||||
import org.keycloak.testsuite.util.*;
|
||||
|
||||
@@ -40,6 +38,8 @@ import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
||||
|
||||
public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
|
||||
protected IdentityProviderResource identityProviderResource;
|
||||
|
||||
@Before
|
||||
public void beforeBrokerTest() {
|
||||
log.debug("creating user for realm " + bc.providerRealmName());
|
||||
@@ -61,7 +61,8 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
|
||||
log.debug("adding identity provider to realm " + bc.consumerRealmName());
|
||||
RealmResource realm = adminClient.realm(bc.consumerRealmName());
|
||||
realm.identityProviders().create(bc.setUpIdentityProvider(suiteContext));
|
||||
realm.identityProviders().create(bc.setUpIdentityProvider(suiteContext)).close();
|
||||
identityProviderResource = realm.identityProviders().get(bc.getIDPAlias());
|
||||
|
||||
// addClients
|
||||
List<ClientRepresentation> clients = bc.createProviderClients(suiteContext);
|
||||
@@ -70,7 +71,7 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
for (ClientRepresentation client : clients) {
|
||||
log.debug("adding client " + client.getName() + " to realm " + bc.providerRealmName());
|
||||
|
||||
providerRealm.clients().create(client);
|
||||
providerRealm.clients().create(client).close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
for (ClientRepresentation client : clients) {
|
||||
log.debug("adding client " + client.getName() + " to realm " + bc.consumerRealmName());
|
||||
|
||||
consumerRealm.clients().create(client);
|
||||
consumerRealm.clients().create(client).close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +91,12 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
|
||||
@Test
|
||||
public void testLogInAsUserInIDP() {
|
||||
loginUser();
|
||||
|
||||
testSingleLogout();
|
||||
}
|
||||
|
||||
protected void loginUser() {
|
||||
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
|
||||
|
||||
log.debug("Clicking social " + bc.getIDPAlias());
|
||||
@@ -98,16 +105,16 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
waitForPage(driver, "log in to");
|
||||
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
|
||||
|
||||
log.debug("Logging in");
|
||||
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
waitForPage(driver, "update account information");
|
||||
|
||||
Assert.assertTrue(updateAccountInformationPage.isCurrent());
|
||||
updateAccountInformationPage.assertCurrent();
|
||||
Assert.assertTrue("We must be on correct realm right now",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/"));
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/"));
|
||||
|
||||
log.debug("Updating info on updateAccount page");
|
||||
updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname", "Lastname");
|
||||
@@ -128,9 +135,7 @@ public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest {
|
||||
}
|
||||
|
||||
Assert.assertTrue("There must be user " + bc.getUserLogin() + " in realm " + bc.consumerRealmName(),
|
||||
isUserFound);
|
||||
|
||||
testSingleLogout();
|
||||
isUserFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+20
-18
@@ -6,6 +6,7 @@
|
||||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.keycloak.protocol.ProtocolMapperUtils;
|
||||
import org.keycloak.protocol.saml.SamlConfigAttributes;
|
||||
import org.keycloak.protocol.saml.SamlProtocol;
|
||||
import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
|
||||
import org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper;
|
||||
@@ -22,6 +23,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.broker.saml.SAMLIdentityProviderConfig.*;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
||||
|
||||
@@ -63,17 +65,17 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
|
||||
attributes.put("saml.authnstatement", "true");
|
||||
attributes.put("saml_single_logout_service_url_post",
|
||||
attributes.put(SamlConfigAttributes.SAML_AUTHNSTATEMENT, "true");
|
||||
attributes.put(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE,
|
||||
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
||||
attributes.put("saml_assertion_consumer_url_post",
|
||||
attributes.put(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE,
|
||||
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
||||
attributes.put("saml_force_name_id_format", "true");
|
||||
attributes.put("saml_name_id_format", "username");
|
||||
attributes.put("saml.assertion.signature", "false");
|
||||
attributes.put("saml.server.signature", "false");
|
||||
attributes.put("saml.client.signature", "false");
|
||||
attributes.put("saml.encrypt", "false");
|
||||
attributes.put(SamlConfigAttributes.SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE, "true");
|
||||
attributes.put(SamlConfigAttributes.SAML_NAME_ID_FORMAT_ATTRIBUTE, "username");
|
||||
attributes.put(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, "false");
|
||||
attributes.put(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "false");
|
||||
attributes.put(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, "false");
|
||||
attributes.put(SamlConfigAttributes.SAML_ENCRYPT, "false");
|
||||
|
||||
client.setAttributes(attributes);
|
||||
|
||||
@@ -133,15 +135,15 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
||||
|
||||
Map<String, String> config = idp.getConfig();
|
||||
|
||||
config.put("singleSignOnServiceUrl", getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/saml");
|
||||
config.put("singleLogoutServiceUrl", getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/saml");
|
||||
config.put("nameIDPolicyFormat", "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
|
||||
config.put("forceAuthn", "true");
|
||||
config.put("postBindingResponse", "true");
|
||||
config.put("postBindingAuthnRequest", "true");
|
||||
config.put("validateSignature", "false");
|
||||
config.put("wantAuthnRequestsSigned", "false");
|
||||
config.put("backchannelSupported", "true");
|
||||
config.put(SINGLE_SIGN_ON_SERVICE_URL, getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/saml");
|
||||
config.put(SINGLE_LOGOUT_SERVICE_URL, getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/saml");
|
||||
config.put(NAME_ID_POLICY_FORMAT, "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
|
||||
config.put(FORCE_AUTHN, "true");
|
||||
config.put(POST_BINDING_RESPONSE, "true");
|
||||
config.put(POST_BINDING_AUTHN_REQUEST, "true");
|
||||
config.put(VALIDATE_SIGNATURE, "false");
|
||||
config.put(WANT_AUTHN_REQUESTS_SIGNED, "false");
|
||||
config.put(BACKCHANNEL_SUPPORTED, "true");
|
||||
|
||||
return idp;
|
||||
}
|
||||
|
||||
+70
-11
@@ -1,19 +1,29 @@
|
||||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
|
||||
import org.keycloak.protocol.saml.SamlConfigAttributes;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
|
||||
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||
import org.keycloak.testsuite.updaters.IdentityProviderAttributeUpdater;
|
||||
import java.io.Closeable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestTools.encodeUrl;
|
||||
|
||||
public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
||||
|
||||
public static class KcSamlSignedBrokerConfiguration extends KcSamlBrokerConfiguration {
|
||||
public class KcSamlSignedBrokerConfiguration extends KcSamlBrokerConfiguration {
|
||||
|
||||
@Override
|
||||
public RealmRepresentation createProviderRealm() {
|
||||
@@ -39,6 +49,9 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
||||
public List<ClientRepresentation> createProviderClients(SuiteContext suiteContext) {
|
||||
List<ClientRepresentation> clientRepresentationList = super.createProviderClients(suiteContext);
|
||||
|
||||
String consumerCert = adminClient.realm(consumerRealmName()).keys().getKeyMetadata().getKeys().get(0).getCertificate();
|
||||
Assert.assertThat(consumerCert, Matchers.notNullValue());
|
||||
|
||||
for (ClientRepresentation client : clientRepresentationList) {
|
||||
client.setClientAuthenticatorType("client-secret");
|
||||
client.setSurrogateAuthRequired(false);
|
||||
@@ -49,12 +62,11 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
||||
client.setAttributes(attributes);
|
||||
}
|
||||
|
||||
attributes.put("saml.assertion.signature", "true");
|
||||
attributes.put("saml.server.signature", "true");
|
||||
attributes.put("saml.client.signature", "true");
|
||||
attributes.put("saml.signature.algorithm", "RSA_SHA256");
|
||||
attributes.put("saml.signing.private.key", IDP_SAML_SIGN_KEY);
|
||||
attributes.put("saml.signing.certificate", IDP_SAML_SIGN_CERT);
|
||||
attributes.put(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, "true");
|
||||
attributes.put(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "true");
|
||||
attributes.put(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, "true");
|
||||
attributes.put(SamlConfigAttributes.SAML_SIGNATURE_ALGORITHM, "RSA_SHA256");
|
||||
attributes.put(SamlConfigAttributes.SAML_SIGNING_CERTIFICATE_ATTRIBUTE, consumerCert);
|
||||
}
|
||||
|
||||
return clientRepresentationList;
|
||||
@@ -64,11 +76,15 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
||||
public IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext) {
|
||||
IdentityProviderRepresentation result = super.setUpIdentityProvider(suiteContext);
|
||||
|
||||
String providerCert = adminClient.realm(providerRealmName()).keys().getKeyMetadata().getKeys().get(0).getCertificate();
|
||||
Assert.assertThat(providerCert, Matchers.notNullValue());
|
||||
|
||||
Map<String, String> config = result.getConfig();
|
||||
|
||||
config.put("validateSignature", "true");
|
||||
config.put("wantAuthnRequestsSigned", "true");
|
||||
config.put("signingCertificate", IDP_SAML_SIGN_CERT);
|
||||
config.put(SAMLIdentityProviderConfig.VALIDATE_SIGNATURE, "true");
|
||||
config.put(SAMLIdentityProviderConfig.WANT_ASSERTIONS_SIGNED, "true");
|
||||
config.put(SAMLIdentityProviderConfig.WANT_AUTHN_REQUESTS_SIGNED, "true");
|
||||
config.put(SAMLIdentityProviderConfig.SIGNING_CERTIFICATE_KEY, providerCert);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -76,7 +92,50 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
||||
|
||||
@Override
|
||||
protected BrokerConfiguration getBrokerConfiguration() {
|
||||
return KcSamlSignedBrokerConfiguration.INSTANCE;
|
||||
return new KcSamlSignedBrokerConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignedEncryptedAssertions() throws Exception {
|
||||
ClientRepresentation client = adminClient.realm(bc.providerRealmName())
|
||||
.clients()
|
||||
.findByClientId(bc.getIDPClientIdInProviderRealm(suiteContext))
|
||||
.get(0);
|
||||
|
||||
final ClientResource clientResource = realmsResouce().realm(bc.providerRealmName()).clients().get(client.getId());
|
||||
Assert.assertThat(clientResource, Matchers.notNullValue());
|
||||
|
||||
String providerCert = adminClient.realm(bc.providerRealmName()).keys().getKeyMetadata().getKeys().get(0).getCertificate();
|
||||
Assert.assertThat(providerCert, Matchers.notNullValue());
|
||||
|
||||
String consumerCert = adminClient.realm(bc.consumerRealmName()).keys().getKeyMetadata().getKeys().get(0).getCertificate();
|
||||
Assert.assertThat(consumerCert, Matchers.notNullValue());
|
||||
|
||||
try (Closeable idpUpdater = new IdentityProviderAttributeUpdater(identityProviderResource)
|
||||
.setAttribute(SAMLIdentityProviderConfig.VALIDATE_SIGNATURE, "true")
|
||||
.setAttribute(SAMLIdentityProviderConfig.WANT_ASSERTIONS_SIGNED, "true")
|
||||
.setAttribute(SAMLIdentityProviderConfig.WANT_ASSERTIONS_ENCRYPTED, "true")
|
||||
.setAttribute(SAMLIdentityProviderConfig.WANT_AUTHN_REQUESTS_SIGNED, "false")
|
||||
.setAttribute(SAMLIdentityProviderConfig.SIGNING_CERTIFICATE_KEY, providerCert)
|
||||
.update();
|
||||
Closeable clientUpdater = new ClientAttributeUpdater(clientResource)
|
||||
.setAttribute(SamlConfigAttributes.SAML_ENCRYPT, "true")
|
||||
.setAttribute(SamlConfigAttributes.SAML_ENCRYPTION_CERTIFICATE_ATTRIBUTE, consumerCert)
|
||||
.setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, "false") // only sign assertions
|
||||
.setAttribute(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, "true")
|
||||
.setAttribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, "false")
|
||||
.update())
|
||||
{
|
||||
// Login should pass because assertion is signed.
|
||||
loginUser();
|
||||
|
||||
// Logout should fail because logout response is not signed.
|
||||
driver.navigate().to(BrokerTestTools.getAuthRoot(suiteContext)
|
||||
+ "/auth/realms/" + bc.providerRealmName()
|
||||
+ "/protocol/" + "openid-connect"
|
||||
+ "/logout?redirect_uri=" + encodeUrl(getAccountUrl(bc.providerRealmName())));
|
||||
|
||||
errorPage.assertCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user