Merge pull request #3537 from hmlnarik/KEYCLOAK-3035
KEYCLOAK-3035 - Fix intermittent failures and refactor broker test
This commit is contained in:
commit
8ee2134e05
9 changed files with 603 additions and 452 deletions
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class Retry {
|
||||
|
||||
public static void execute(Runnable runnable, int retryCount, long intervalMillis) {
|
||||
while (true) {
|
||||
try {
|
||||
runnable.run();
|
||||
return;
|
||||
} catch (RuntimeException e) {
|
||||
retryCount--;
|
||||
if (retryCount > 0) {
|
||||
try {
|
||||
Thread.sleep(intervalMillis);
|
||||
} catch (InterruptedException ie) {
|
||||
ie.addSuppressed(e);
|
||||
throw new RuntimeException(ie);
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -6,25 +6,19 @@ import org.junit.Test;
|
|||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.UsersResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.Retry;
|
||||
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
||||
import org.keycloak.testsuite.pages.ErrorPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -32,6 +26,7 @@ import static org.junit.Assert.assertTrue;
|
|||
import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
|
||||
import static org.keycloak.testsuite.admin.ApiUtil.resetUserPassword;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
||||
import org.keycloak.testsuite.pages.IdpConfirmLinkPage;
|
||||
import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
|
||||
import org.keycloak.testsuite.util.MailServer;
|
||||
|
@ -40,23 +35,6 @@ import org.keycloak.testsuite.util.UserBuilder;
|
|||
|
||||
public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
||||
|
||||
protected abstract RealmRepresentation createProviderRealm();
|
||||
protected abstract RealmRepresentation createConsumerRealm();
|
||||
|
||||
protected abstract List<ClientRepresentation> createProviderClients();
|
||||
protected abstract List<ClientRepresentation> createConsumerClients();
|
||||
|
||||
protected abstract IdentityProviderRepresentation setUpIdentityProvider();
|
||||
|
||||
protected abstract String providerRealmName();
|
||||
protected abstract String consumerRealmName();
|
||||
|
||||
protected abstract String getUserLogin();
|
||||
protected abstract String getUserPassword();
|
||||
protected abstract String getUserEmail();
|
||||
|
||||
protected abstract String getIDPAlias();
|
||||
|
||||
@Page
|
||||
protected LoginPage accountLoginPage;
|
||||
|
||||
|
@ -72,10 +50,18 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
@Page
|
||||
protected IdpConfirmLinkPage idpConfirmLinkPage;
|
||||
|
||||
protected BrokerConfiguration bc = getBrokerConfiguration();
|
||||
|
||||
/**
|
||||
* Returns a broker configuration. Return value should not change between calls.
|
||||
* @return
|
||||
*/
|
||||
protected abstract BrokerConfiguration getBrokerConfiguration();
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
RealmRepresentation providerRealm = createProviderRealm();
|
||||
RealmRepresentation consumerRealm = createConsumerRealm();
|
||||
RealmRepresentation providerRealm = bc.createProviderRealm();
|
||||
RealmRepresentation consumerRealm = bc.createConsumerRealm();
|
||||
|
||||
testRealms.add(providerRealm);
|
||||
testRealms.add(consumerRealm);
|
||||
|
@ -83,45 +69,45 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
|
||||
@Before
|
||||
public void createUser() {
|
||||
log.debug("creating user for realm " + providerRealmName());
|
||||
log.debug("creating user for realm " + bc.providerRealmName());
|
||||
|
||||
UserRepresentation user = new UserRepresentation();
|
||||
user.setUsername(getUserLogin());
|
||||
user.setEmail(getUserEmail());
|
||||
user.setUsername(bc.getUserLogin());
|
||||
user.setEmail(bc.getUserEmail());
|
||||
user.setEmailVerified(true);
|
||||
user.setEnabled(true);
|
||||
|
||||
RealmResource realmResource = adminClient.realm(providerRealmName());
|
||||
RealmResource realmResource = adminClient.realm(bc.providerRealmName());
|
||||
String userId = createUserWithAdminClient(realmResource, user);
|
||||
|
||||
resetUserPassword(realmResource.users().get(userId), getUserPassword(), false);
|
||||
resetUserPassword(realmResource.users().get(userId), bc.getUserPassword(), false);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void addIdentityProviderToProviderRealm() {
|
||||
log.debug("adding identity provider to realm " + consumerRealmName());
|
||||
log.debug("adding identity provider to realm " + bc.consumerRealmName());
|
||||
|
||||
RealmResource realm = adminClient.realm(consumerRealmName());
|
||||
realm.identityProviders().create(setUpIdentityProvider());
|
||||
RealmResource realm = adminClient.realm(bc.consumerRealmName());
|
||||
realm.identityProviders().create(bc.setUpIdentityProvider(suiteContext));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void addClients() {
|
||||
List<ClientRepresentation> clients = createProviderClients();
|
||||
List<ClientRepresentation> clients = bc.createProviderClients(suiteContext);
|
||||
if (clients != null) {
|
||||
RealmResource providerRealm = adminClient.realm(providerRealmName());
|
||||
RealmResource providerRealm = adminClient.realm(bc.providerRealmName());
|
||||
for (ClientRepresentation client : clients) {
|
||||
log.debug("adding client " + client.getName() + " to realm " + providerRealmName());
|
||||
log.debug("adding client " + client.getName() + " to realm " + bc.providerRealmName());
|
||||
|
||||
providerRealm.clients().create(client);
|
||||
}
|
||||
}
|
||||
|
||||
clients = createConsumerClients();
|
||||
clients = bc.createConsumerClients(suiteContext);
|
||||
if (clients != null) {
|
||||
RealmResource consumerRealm = adminClient.realm(consumerRealmName());
|
||||
RealmResource consumerRealm = adminClient.realm(bc.consumerRealmName());
|
||||
for (ClientRepresentation client : clients) {
|
||||
log.debug("adding client " + client.getName() + " to realm " + consumerRealmName());
|
||||
log.debug("adding client " + client.getName() + " to realm " + bc.consumerRealmName());
|
||||
|
||||
consumerRealm.clients().create(client);
|
||||
}
|
||||
|
@ -132,42 +118,31 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
return suiteContext.getAuthServerInfo().getContextRoot().toString();
|
||||
}
|
||||
|
||||
protected IdentityProviderRepresentation createIdentityProvider(String alias, String providerId) {
|
||||
IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
|
||||
|
||||
identityProviderRepresentation.setAlias(alias);
|
||||
identityProviderRepresentation.setDisplayName(providerId);
|
||||
identityProviderRepresentation.setProviderId(providerId);
|
||||
identityProviderRepresentation.setEnabled(true);
|
||||
|
||||
return identityProviderRepresentation;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logInAsUserInIDP() {
|
||||
driver.navigate().to(getAccountUrl(consumerRealmName()));
|
||||
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
|
||||
|
||||
log.debug("Clicking social " + getIDPAlias());
|
||||
accountLoginPage.clickSocial(getIDPAlias());
|
||||
log.debug("Clicking social " + bc.getIDPAlias());
|
||||
accountLoginPage.clickSocial(bc.getIDPAlias());
|
||||
|
||||
waitForPage("log in to");
|
||||
waitForPage(driver, "log in to");
|
||||
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName() + "/"));
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
|
||||
|
||||
log.debug("Logging in");
|
||||
accountLoginPage.login(getUserLogin(), getUserPassword());
|
||||
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
waitForPage("update account information");
|
||||
waitForPage(driver, "update account information");
|
||||
|
||||
Assert.assertTrue(updateAccountInformationPage.isCurrent());
|
||||
Assert.assertTrue("We must be on correct realm right now",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + consumerRealmName() + "/"));
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/"));
|
||||
|
||||
log.debug("Updating info on updateAccount page");
|
||||
updateAccountInformationPage.updateAccountInformation("Firstname", "Lastname");
|
||||
|
||||
UsersResource consumerUsers = adminClient.realm(consumerRealmName()).users();
|
||||
UsersResource consumerUsers = adminClient.realm(bc.consumerRealmName()).users();
|
||||
|
||||
int userCount = consumerUsers.count();
|
||||
Assert.assertTrue("There must be at least one user", userCount > 0);
|
||||
|
@ -176,13 +151,13 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
|
||||
boolean isUserFound = false;
|
||||
for (UserRepresentation user : users) {
|
||||
if (user.getUsername().equals(getUserLogin()) && user.getEmail().equals(getUserEmail())) {
|
||||
if (user.getUsername().equals(bc.getUserLogin()) && user.getEmail().equals(bc.getUserEmail())) {
|
||||
isUserFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue("There must be user " + getUserLogin() + " in realm " + consumerRealmName(),
|
||||
Assert.assertTrue("There must be user " + bc.getUserLogin() + " in realm " + bc.consumerRealmName(),
|
||||
isUserFound);
|
||||
|
||||
testSingleLogout();
|
||||
|
@ -192,22 +167,22 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
public void loginWithExistingUser() {
|
||||
logInAsUserInIDP();
|
||||
|
||||
Integer userCount = adminClient.realm(consumerRealmName()).users().count();
|
||||
Integer userCount = adminClient.realm(bc.consumerRealmName()).users().count();
|
||||
|
||||
driver.navigate().to(getAccountUrl(consumerRealmName()));
|
||||
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
|
||||
|
||||
log.debug("Clicking social " + getIDPAlias());
|
||||
accountLoginPage.clickSocial(getIDPAlias());
|
||||
log.debug("Clicking social " + bc.getIDPAlias());
|
||||
accountLoginPage.clickSocial(bc.getIDPAlias());
|
||||
|
||||
waitForPage("log in to");
|
||||
waitForPage(driver, "log in to");
|
||||
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName() + "/"));
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
|
||||
|
||||
accountLoginPage.login(getUserLogin(), getUserPassword());
|
||||
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
assertEquals(accountPage.buildUri().toASCIIString().replace("master", "consumer") + "/", driver.getCurrentUrl());
|
||||
|
||||
assertEquals(userCount, adminClient.realm(consumerRealmName()).users().count());
|
||||
assertEquals(userCount, adminClient.realm(bc.consumerRealmName()).users().count());
|
||||
}
|
||||
|
||||
// KEYCLOAK-2957
|
||||
|
@ -219,40 +194,40 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
|
||||
try {
|
||||
//configure smpt server in the realm
|
||||
RealmRepresentation master = adminClient.realm(consumerRealmName()).toRepresentation();
|
||||
RealmRepresentation master = adminClient.realm(bc.consumerRealmName()).toRepresentation();
|
||||
master.setSmtpServer(suiteContext.getSmtpServer());
|
||||
adminClient.realm(consumerRealmName()).update(master);
|
||||
adminClient.realm(bc.consumerRealmName()).update(master);
|
||||
|
||||
//create user on consumer's site who should be linked later
|
||||
UserRepresentation newUser = UserBuilder.create().username("consumer").email(USER_EMAIL).enabled(true).build();
|
||||
String userId = createUserWithAdminClient(adminClient.realm(consumerRealmName()), newUser);
|
||||
resetUserPassword(adminClient.realm(consumerRealmName()).users().get(userId), "password", false);
|
||||
String userId = createUserWithAdminClient(adminClient.realm(bc.consumerRealmName()), newUser);
|
||||
resetUserPassword(adminClient.realm(bc.consumerRealmName()).users().get(userId), "password", false);
|
||||
|
||||
//test
|
||||
driver.navigate().to(getAccountUrl(consumerRealmName()));
|
||||
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
|
||||
|
||||
log.debug("Clicking social " + getIDPAlias());
|
||||
accountLoginPage.clickSocial(getIDPAlias());
|
||||
log.debug("Clicking social " + bc.getIDPAlias());
|
||||
accountLoginPage.clickSocial(bc.getIDPAlias());
|
||||
|
||||
waitForPage("log in to");
|
||||
waitForPage(driver, "log in to");
|
||||
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName() + "/"));
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
|
||||
|
||||
log.debug("Logging in");
|
||||
accountLoginPage.login(getUserLogin(), getUserPassword());
|
||||
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
waitForPage("update account information");
|
||||
waitForPage(driver, "update account information");
|
||||
|
||||
Assert.assertTrue(updateAccountInformationPage.isCurrent());
|
||||
Assert.assertTrue("We must be on correct realm right now",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + consumerRealmName() + "/"));
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/"));
|
||||
|
||||
log.debug("Updating info on updateAccount page");
|
||||
updateAccountInformationPage.updateAccountInformation("Firstname", "Lastname");
|
||||
|
||||
//link account by email
|
||||
waitForPage("account already exists");
|
||||
waitForPage(driver, "account already exists");
|
||||
idpConfirmLinkPage.clickLinkAccount();
|
||||
|
||||
String url = assertEmailAndGetUrl(MailServerConfiguration.FROM, USER_EMAIL,
|
||||
|
@ -265,7 +240,7 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
assertEquals(accountPage.buildUri().toASCIIString().replace("master", "consumer") + "/", driver.getCurrentUrl());
|
||||
|
||||
//test if the user has verified email
|
||||
assertTrue(adminClient.realm(consumerRealmName()).users().get(userId).toRepresentation().isEmailVerified());
|
||||
assertTrue(adminClient.realm(bc.consumerRealmName()).users().get(userId).toRepresentation().isEmailVerified());
|
||||
} finally {
|
||||
// stop mail server
|
||||
MailServer.stop();
|
||||
|
@ -275,23 +250,20 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
// KEYCLOAK-3267
|
||||
@Test
|
||||
public void loginWithExistingUserWithBruteForceEnabled() {
|
||||
adminClient.realm(consumerRealmName()).update(RealmBuilder.create().bruteForceProtected(true).failureFactor(2).build());
|
||||
adminClient.realm(bc.consumerRealmName()).update(RealmBuilder.create().bruteForceProtected(true).failureFactor(2).build());
|
||||
|
||||
loginWithExistingUser();
|
||||
|
||||
driver.navigate().to(getAccountPasswordUrl(consumerRealmName()));
|
||||
driver.navigate().to(getAccountPasswordUrl(bc.consumerRealmName()));
|
||||
|
||||
accountPasswordPage.changePassword("password", "password");
|
||||
|
||||
driver.navigate().to(getAuthRoot()
|
||||
+ "/auth/realms/" + providerRealmName()
|
||||
+ "/protocol/" + "openid-connect"
|
||||
+ "/logout?redirect_uri=" + encodeUrl(getAccountUrl(providerRealmName())));
|
||||
logoutFromRealm(bc.providerRealmName());
|
||||
|
||||
driver.navigate().to(getAccountUrl(consumerRealmName()));
|
||||
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
|
||||
|
||||
try {
|
||||
waitForPage("log in to");
|
||||
waitForPage(driver, "log in to");
|
||||
} catch (TimeoutException e) {
|
||||
log.debug(driver.getTitle());
|
||||
log.debug(driver.getPageSource());
|
||||
|
@ -300,53 +272,71 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
waitForElementEnabled("login");
|
||||
waitForElementEnabled(driver, "login");
|
||||
} catch (TimeoutException e) {
|
||||
Assert.fail("Timeout while waiting for login element enabled");
|
||||
}
|
||||
|
||||
accountLoginPage.login(getUserLogin(), "invalid");
|
||||
accountLoginPage.login(bc.getUserLogin(), "invalid");
|
||||
}
|
||||
|
||||
assertEquals("Invalid username or password.", accountLoginPage.getError());
|
||||
|
||||
accountLoginPage.clickSocial(getIDPAlias());
|
||||
accountLoginPage.clickSocial(bc.getIDPAlias());
|
||||
|
||||
try {
|
||||
waitForPage("log in to");
|
||||
waitForPage(driver, "log in to");
|
||||
} catch (TimeoutException e) {
|
||||
log.debug(driver.getTitle());
|
||||
log.debug(driver.getPageSource());
|
||||
Assert.fail("Timeout while waiting for login page");
|
||||
}
|
||||
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName() + "/"));
|
||||
Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
|
||||
|
||||
accountLoginPage.login(getUserLogin(), getUserPassword());
|
||||
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
assertEquals("Account is disabled, contact admin.", errorPage.getError());
|
||||
}
|
||||
|
||||
private void testSingleLogout() {
|
||||
protected void logoutFromRealm(String realm) {
|
||||
driver.navigate().to(getAuthRoot()
|
||||
+ "/auth/realms/" + realm
|
||||
+ "/protocol/" + "openid-connect"
|
||||
+ "/logout?redirect_uri=" + encodeUrl(getAccountUrl(realm)));
|
||||
|
||||
try {
|
||||
Retry.execute(() -> {
|
||||
try {
|
||||
waitForPage(driver, "log in to " + realm);
|
||||
} catch (TimeoutException ex) {
|
||||
driver.navigate().refresh();
|
||||
log.debug("[Retriable] Timed out waiting for login page");
|
||||
throw ex;
|
||||
}
|
||||
}, 10, 100);
|
||||
} catch (TimeoutException e) {
|
||||
log.debug(driver.getTitle());
|
||||
log.debug(driver.getPageSource());
|
||||
Assert.fail("Timeout while waiting for login page");
|
||||
}
|
||||
}
|
||||
|
||||
protected void testSingleLogout() {
|
||||
log.debug("Testing single log out");
|
||||
|
||||
driver.navigate().to(getAccountUrl(providerRealmName()));
|
||||
driver.navigate().to(getAccountUrl(bc.providerRealmName()));
|
||||
|
||||
Assert.assertTrue("Should be logged in the account page", driver.getTitle().endsWith("Account Management"));
|
||||
|
||||
driver.navigate().to(getAuthRoot()
|
||||
+ "/auth/realms/" + providerRealmName()
|
||||
+ "/protocol/" + "openid-connect"
|
||||
+ "/logout?redirect_uri=" + encodeUrl(getAccountUrl(providerRealmName())));
|
||||
logoutFromRealm(bc.providerRealmName());
|
||||
|
||||
waitForPage("log in to " + providerRealmName());
|
||||
Assert.assertTrue("Should be on " + bc.providerRealmName() + " realm", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName()));
|
||||
|
||||
Assert.assertTrue("Should be on " + providerRealmName() + " realm", driver.getCurrentUrl().contains("/auth/realms/" + providerRealmName()));
|
||||
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
|
||||
|
||||
driver.navigate().to(getAccountUrl(consumerRealmName()));
|
||||
|
||||
Assert.assertTrue("Should be on " + consumerRealmName() + " realm on login page",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + consumerRealmName() + "/protocol/openid-connect/"));
|
||||
Assert.assertTrue("Should be on " + bc.consumerRealmName() + " realm on login page",
|
||||
driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/protocol/openid-connect/"));
|
||||
}
|
||||
|
||||
private String getAccountUrl(String realmName) {
|
||||
|
@ -356,45 +346,4 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
|||
private String getAccountPasswordUrl(String realmName) {
|
||||
return getAuthRoot() + "/auth/realms/" + realmName + "/account/password";
|
||||
}
|
||||
|
||||
private void waitForPage(final String title) {
|
||||
WebDriverWait wait = new WebDriverWait(driver, 5);
|
||||
|
||||
ExpectedCondition<Boolean> condition = new ExpectedCondition<Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(WebDriver input) {
|
||||
return input.getTitle().toLowerCase().contains(title);
|
||||
}
|
||||
};
|
||||
|
||||
wait.until(condition);
|
||||
}
|
||||
|
||||
private void waitForElementEnabled(final String elementName) {
|
||||
WebDriverWait wait = new WebDriverWait(driver, 5);
|
||||
|
||||
ExpectedCondition<Boolean> condition = new ExpectedCondition<Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(WebDriver input) {
|
||||
List<WebElement> elements = input.findElements(By.name(elementName));
|
||||
if (elements.size() == 0)
|
||||
return false;
|
||||
|
||||
return elements.get(0).isEnabled();
|
||||
}
|
||||
};
|
||||
|
||||
wait.until(condition);
|
||||
}
|
||||
|
||||
private String encodeUrl(String url) {
|
||||
String result;
|
||||
try {
|
||||
result = URLEncoder.encode(url, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
result = url;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
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 java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public interface BrokerConfiguration {
|
||||
|
||||
/**
|
||||
* @return Representation of the realm at the identity provider side.
|
||||
*/
|
||||
RealmRepresentation createProviderRealm();
|
||||
|
||||
/**
|
||||
* @return Representation of the realm at the broker side.
|
||||
*/
|
||||
RealmRepresentation createConsumerRealm();
|
||||
|
||||
List<ClientRepresentation> createProviderClients(SuiteContext suiteContext);
|
||||
|
||||
List<ClientRepresentation> createConsumerClients(SuiteContext suiteContext);
|
||||
|
||||
/**
|
||||
* @return Representation of the identity provider for declaration in the broker
|
||||
*/
|
||||
IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext);
|
||||
|
||||
/**
|
||||
* @return Name of realm containing identity provider. Must be consistent with {@link #createProviderRealm()}
|
||||
*/
|
||||
String providerRealmName();
|
||||
|
||||
/**
|
||||
* @return Realm name of the broker. Must be consistent with {@link #createConsumerRealm()}
|
||||
*/
|
||||
String consumerRealmName();
|
||||
|
||||
/**
|
||||
* @return User login name of the brokered user
|
||||
*/
|
||||
String getUserLogin();
|
||||
|
||||
/**
|
||||
* @return Password of the brokered user
|
||||
*/
|
||||
String getUserPassword();
|
||||
|
||||
/**
|
||||
* @return E-mail of the brokered user
|
||||
*/
|
||||
String getUserEmail();
|
||||
|
||||
/**
|
||||
* @return Alias of the identity provider as defined in the broker realm
|
||||
*/
|
||||
String getIDPAlias();
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class BrokerTestTools {
|
||||
|
||||
public static String getAuthRoot(SuiteContext suiteContext) {
|
||||
return suiteContext.getAuthServerInfo().getContextRoot().toString();
|
||||
}
|
||||
|
||||
public static IdentityProviderRepresentation createIdentityProvider(String alias, String providerId) {
|
||||
IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
|
||||
|
||||
identityProviderRepresentation.setAlias(alias);
|
||||
identityProviderRepresentation.setDisplayName(providerId);
|
||||
identityProviderRepresentation.setProviderId(providerId);
|
||||
identityProviderRepresentation.setEnabled(true);
|
||||
|
||||
return identityProviderRepresentation;
|
||||
}
|
||||
|
||||
public static void waitForPage(WebDriver driver, final String title) {
|
||||
WebDriverWait wait = new WebDriverWait(driver, 5);
|
||||
|
||||
ExpectedCondition<Boolean> condition = (WebDriver input) -> input.getTitle().toLowerCase().contains(title);
|
||||
|
||||
wait.until(condition);
|
||||
}
|
||||
|
||||
public static void waitForElementEnabled(WebDriver driver, final String elementName) {
|
||||
WebDriverWait wait = new WebDriverWait(driver, 5);
|
||||
|
||||
ExpectedCondition<Boolean> condition = (WebDriver input) -> {
|
||||
List<WebElement> elements = input.findElements(By.name(elementName));
|
||||
return (! elements.isEmpty()) && elements.get(0).isEnabled();
|
||||
};
|
||||
|
||||
wait.until(condition);
|
||||
}
|
||||
|
||||
public static String encodeUrl(String url) {
|
||||
String result;
|
||||
try {
|
||||
result = URLEncoder.encode(url, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
result = url;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class KcOidcBrokerConfiguration implements BrokerConfiguration {
|
||||
|
||||
public static final KcOidcBrokerConfiguration INSTANCE = new KcOidcBrokerConfiguration();
|
||||
|
||||
@Override
|
||||
public RealmRepresentation createProviderRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
realm.setRealm(REALM_PROV_NAME);
|
||||
realm.setEnabled(true);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmRepresentation createConsumerRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
realm.setRealm(REALM_CONS_NAME);
|
||||
realm.setEnabled(true);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientRepresentation> createProviderClients(SuiteContext suiteContext) {
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
client.setId(CLIENT_ID);
|
||||
client.setName(CLIENT_ID);
|
||||
client.setSecret(CLIENT_SECRET);
|
||||
client.setEnabled(true);
|
||||
|
||||
client.setRedirectUris(Collections.singletonList(getAuthRoot(suiteContext) +
|
||||
"/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_OIDC_ALIAS + "/endpoint/*"));
|
||||
|
||||
client.setAdminUrl(getAuthRoot(suiteContext) +
|
||||
"/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_OIDC_ALIAS + "/endpoint");
|
||||
|
||||
return Collections.singletonList(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientRepresentation> createConsumerClients(SuiteContext suiteContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext) {
|
||||
IdentityProviderRepresentation idp = createIdentityProvider(IDP_OIDC_ALIAS, IDP_OIDC_PROVIDER_ID);
|
||||
|
||||
Map<String, String> config = idp.getConfig();
|
||||
|
||||
config.put("clientId", CLIENT_ID);
|
||||
config.put("clientSecret", CLIENT_SECRET);
|
||||
config.put("prompt", "login");
|
||||
config.put("authorizationUrl", getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/auth");
|
||||
config.put("tokenUrl", getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/token");
|
||||
config.put("logoutUrl", getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/logout");
|
||||
config.put("userInfoUrl", getAuthRoot(suiteContext) + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/userinfo");
|
||||
config.put("defaultScope", "email profile");
|
||||
config.put("backchannelSupported", "true");
|
||||
|
||||
return idp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserLogin() {
|
||||
return USER_LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserPassword() {
|
||||
return USER_PASSWORD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserEmail() {
|
||||
return USER_EMAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String providerRealmName() {
|
||||
return REALM_PROV_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String consumerRealmName() {
|
||||
return REALM_CONS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIDPAlias() {
|
||||
return IDP_OIDC_ALIAS;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +1,9 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.CLIENT_ID;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.CLIENT_SECRET;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_OIDC_ALIAS;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_OIDC_PROVIDER_ID;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PROV_NAME;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_LOGIN;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_PASSWORD;
|
||||
|
||||
public class KcOidcBrokerTest extends AbstractBrokerTest {
|
||||
|
||||
@Override
|
||||
protected RealmRepresentation createProviderRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
realm.setRealm(REALM_PROV_NAME);
|
||||
realm.setEnabled(true);
|
||||
|
||||
return realm;
|
||||
protected BrokerConfiguration getBrokerConfiguration() {
|
||||
return KcOidcBrokerConfiguration.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RealmRepresentation createConsumerRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
realm.setRealm(REALM_CONS_NAME);
|
||||
realm.setEnabled(true);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ClientRepresentation> createProviderClients() {
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
client.setId(CLIENT_ID);
|
||||
client.setName(CLIENT_ID);
|
||||
client.setSecret(CLIENT_SECRET);
|
||||
client.setEnabled(true);
|
||||
|
||||
client.setRedirectUris(Collections.singletonList(getAuthRoot() +
|
||||
"/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_OIDC_ALIAS + "/endpoint/*"));
|
||||
|
||||
client.setAdminUrl(getAuthRoot() +
|
||||
"/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_OIDC_ALIAS + "/endpoint");
|
||||
|
||||
return Collections.singletonList(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ClientRepresentation> createConsumerClients() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IdentityProviderRepresentation setUpIdentityProvider() {
|
||||
IdentityProviderRepresentation idp = createIdentityProvider(IDP_OIDC_ALIAS, IDP_OIDC_PROVIDER_ID);
|
||||
|
||||
Map<String, String> config = idp.getConfig();
|
||||
|
||||
config.put("clientId", CLIENT_ID);
|
||||
config.put("clientSecret", CLIENT_SECRET);
|
||||
config.put("prompt", "login");
|
||||
config.put("authorizationUrl", getAuthRoot() + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/auth");
|
||||
config.put("tokenUrl", getAuthRoot() + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/token");
|
||||
config.put("logoutUrl", getAuthRoot() + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/logout");
|
||||
config.put("userInfoUrl", getAuthRoot() + "/auth/realms/" + REALM_PROV_NAME + "/protocol/openid-connect/userinfo");
|
||||
config.put("defaultScope", "email profile");
|
||||
config.put("backchannelSupported", "true");
|
||||
|
||||
return idp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserLogin() {
|
||||
return USER_LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserPassword() {
|
||||
return USER_PASSWORD;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserEmail() {
|
||||
return USER_EMAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String providerRealmName() {
|
||||
return REALM_PROV_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String consumerRealmName() {
|
||||
return REALM_CONS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getIDPAlias() {
|
||||
return IDP_OIDC_ALIAS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestTools.*;
|
||||
|
||||
|
||||
public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
||||
|
||||
public static final KcSamlBrokerConfiguration INSTANCE = new KcSamlBrokerConfiguration();
|
||||
|
||||
@Override
|
||||
public RealmRepresentation createProviderRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
|
||||
realm.setEnabled(true);
|
||||
realm.setRealm(REALM_PROV_NAME);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmRepresentation createConsumerRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
|
||||
realm.setEnabled(true);
|
||||
realm.setRealm(REALM_CONS_NAME);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientRepresentation> createProviderClients(SuiteContext suiteContext) {
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
|
||||
client.setClientId(getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME);
|
||||
client.setEnabled(true);
|
||||
client.setProtocol(IDP_SAML_PROVIDER_ID);
|
||||
client.setRedirectUris(Collections.singletonList(
|
||||
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint"
|
||||
));
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
|
||||
attributes.put("saml.authnstatement", "true");
|
||||
attributes.put("saml_single_logout_service_url_post",
|
||||
getAuthRoot(suiteContext) + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
||||
attributes.put("saml_assertion_consumer_url_post",
|
||||
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");
|
||||
|
||||
client.setAttributes(attributes);
|
||||
|
||||
ProtocolMapperRepresentation mapper = new ProtocolMapperRepresentation();
|
||||
mapper.setName("email");
|
||||
mapper.setProtocol("saml");
|
||||
mapper.setProtocolMapper("saml-user-property-mapper");
|
||||
mapper.setConsentRequired(false);
|
||||
|
||||
Map<String, String> mapperConfig = mapper.getConfig();
|
||||
mapperConfig.put("user.attribute", "email");
|
||||
mapperConfig.put("attribute.name", "urn:oid:1.2.840.113549.1.9.1");
|
||||
mapperConfig.put("attribute.nameformat", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
|
||||
mapperConfig.put("friendly.name", "email");
|
||||
|
||||
client.setProtocolMappers(Collections.singletonList(
|
||||
mapper
|
||||
));
|
||||
|
||||
return Collections.singletonList(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientRepresentation> createConsumerClients(SuiteContext suiteContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext) {
|
||||
IdentityProviderRepresentation idp = createIdentityProvider(IDP_SAML_ALIAS, IDP_SAML_PROVIDER_ID);
|
||||
|
||||
idp.setTrustEmail(true);
|
||||
idp.setAddReadTokenRoleOnCreate(true);
|
||||
idp.setStoreToken(true);
|
||||
|
||||
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");
|
||||
|
||||
return idp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String providerRealmName() {
|
||||
return REALM_PROV_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String consumerRealmName() {
|
||||
return REALM_CONS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserLogin() {
|
||||
return USER_LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserPassword() {
|
||||
return USER_PASSWORD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserEmail() {
|
||||
return USER_EMAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIDPAlias() {
|
||||
return IDP_SAML_ALIAS;
|
||||
}
|
||||
}
|
|
@ -1,148 +1,9 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_SAML_ALIAS;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_SAML_PROVIDER_ID;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PROV_NAME;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_LOGIN;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_PASSWORD;
|
||||
|
||||
@Ignore
|
||||
public class KcSamlBrokerTest extends AbstractBrokerTest {
|
||||
|
||||
@Override
|
||||
protected RealmRepresentation createProviderRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
|
||||
realm.setEnabled(true);
|
||||
realm.setRealm(REALM_PROV_NAME);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RealmRepresentation createConsumerRealm() {
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
|
||||
realm.setEnabled(true);
|
||||
realm.setRealm(REALM_CONS_NAME);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ClientRepresentation> createProviderClients() {
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
|
||||
client.setClientId(getAuthRoot() + "/auth/realms/" + REALM_CONS_NAME);
|
||||
client.setEnabled(true);
|
||||
client.setProtocol(IDP_SAML_PROVIDER_ID);
|
||||
client.setRedirectUris(Collections.singletonList(
|
||||
getAuthRoot() + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint"
|
||||
));
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
|
||||
attributes.put("saml.authnstatement", "true");
|
||||
attributes.put("saml_single_logout_service_url_post",
|
||||
getAuthRoot() + "/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_SAML_ALIAS + "/endpoint");
|
||||
attributes.put("saml_assertion_consumer_url_post",
|
||||
getAuthRoot() + "/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");
|
||||
|
||||
client.setAttributes(attributes);
|
||||
|
||||
ProtocolMapperRepresentation mapper = new ProtocolMapperRepresentation();
|
||||
mapper.setName("email");
|
||||
mapper.setProtocol("saml");
|
||||
mapper.setProtocolMapper("saml-user-property-mapper");
|
||||
mapper.setConsentRequired(false);
|
||||
|
||||
Map<String, String> mapperConfig = mapper.getConfig();
|
||||
mapperConfig.put("user.attribute", "email");
|
||||
mapperConfig.put("attribute.name", "urn:oid:1.2.840.113549.1.9.1");
|
||||
mapperConfig.put("attribute.nameformat", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
|
||||
mapperConfig.put("friendly.name", "email");
|
||||
|
||||
client.setProtocolMappers(Collections.singletonList(
|
||||
mapper
|
||||
));
|
||||
|
||||
return Collections.singletonList(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ClientRepresentation> createConsumerClients() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IdentityProviderRepresentation setUpIdentityProvider() {
|
||||
IdentityProviderRepresentation idp = createIdentityProvider(IDP_SAML_ALIAS, IDP_SAML_PROVIDER_ID);
|
||||
|
||||
idp.setTrustEmail(true);
|
||||
idp.setAddReadTokenRoleOnCreate(true);
|
||||
idp.setStoreToken(true);
|
||||
|
||||
Map<String, String> config = idp.getConfig();
|
||||
|
||||
config.put("singleSignOnServiceUrl", getAuthRoot() + "/auth/realms/" + REALM_PROV_NAME + "/protocol/saml");
|
||||
config.put("singleLogoutServiceUrl", getAuthRoot() + "/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");
|
||||
|
||||
return idp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String providerRealmName() {
|
||||
return REALM_PROV_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String consumerRealmName() {
|
||||
return REALM_CONS_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserLogin() {
|
||||
return USER_LOGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserPassword() {
|
||||
return USER_PASSWORD;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserEmail() {
|
||||
return USER_EMAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getIDPAlias() {
|
||||
return IDP_SAML_ALIAS;
|
||||
protected BrokerConfiguration getBrokerConfiguration() {
|
||||
return KcSamlBrokerConfiguration.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,84 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.junit.Ignore;
|
||||
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 java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_SAML_SIGN_CERT;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_SAML_SIGN_KEY;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PRIVATE_KEY;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PUBLIC_KEY;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.*;
|
||||
|
||||
@Ignore
|
||||
public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
||||
|
||||
@Override
|
||||
protected RealmRepresentation createProviderRealm() {
|
||||
RealmRepresentation realm = super.createProviderRealm();
|
||||
public static class KcSamlSignedBrokerConfiguration extends KcSamlBrokerConfiguration {
|
||||
|
||||
realm.setPublicKey(REALM_PUBLIC_KEY);
|
||||
realm.setPrivateKey(REALM_PRIVATE_KEY);
|
||||
public static final KcSamlSignedBrokerConfiguration INSTANCE = new KcSamlSignedBrokerConfiguration();
|
||||
|
||||
return realm;
|
||||
}
|
||||
@Override
|
||||
public RealmRepresentation createProviderRealm() {
|
||||
RealmRepresentation realm = super.createProviderRealm();
|
||||
|
||||
@Override
|
||||
protected RealmRepresentation createConsumerRealm() {
|
||||
RealmRepresentation realm = super.createConsumerRealm();
|
||||
realm.setPublicKey(REALM_PUBLIC_KEY);
|
||||
realm.setPrivateKey(REALM_PRIVATE_KEY);
|
||||
|
||||
realm.setPublicKey(REALM_PUBLIC_KEY);
|
||||
realm.setPrivateKey(REALM_PRIVATE_KEY);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ClientRepresentation> createProviderClients() {
|
||||
List<ClientRepresentation> clientRepresentationList = super.createProviderClients();
|
||||
|
||||
for (ClientRepresentation client : clientRepresentationList) {
|
||||
client.setClientAuthenticatorType("client-secret");
|
||||
client.setSurrogateAuthRequired(false);
|
||||
|
||||
Map<String, String> attributes = client.getAttributes();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<>();
|
||||
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);
|
||||
return realm;
|
||||
}
|
||||
|
||||
return clientRepresentationList;
|
||||
@Override
|
||||
public RealmRepresentation createConsumerRealm() {
|
||||
RealmRepresentation realm = super.createConsumerRealm();
|
||||
|
||||
realm.setPublicKey(REALM_PUBLIC_KEY);
|
||||
realm.setPrivateKey(REALM_PRIVATE_KEY);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientRepresentation> createProviderClients(SuiteContext suiteContext) {
|
||||
List<ClientRepresentation> clientRepresentationList = super.createProviderClients(suiteContext);
|
||||
|
||||
for (ClientRepresentation client : clientRepresentationList) {
|
||||
client.setClientAuthenticatorType("client-secret");
|
||||
client.setSurrogateAuthRequired(false);
|
||||
|
||||
Map<String, String> attributes = client.getAttributes();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<>();
|
||||
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);
|
||||
}
|
||||
|
||||
return clientRepresentationList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext) {
|
||||
IdentityProviderRepresentation result = super.setUpIdentityProvider(suiteContext);
|
||||
|
||||
Map<String, String> config = result.getConfig();
|
||||
|
||||
config.put("validateSignature", "true");
|
||||
config.put("wantAuthnRequestsSigned", "true");
|
||||
config.put("signingCertificate", IDP_SAML_SIGN_CERT);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IdentityProviderRepresentation setUpIdentityProvider() {
|
||||
IdentityProviderRepresentation result = super.setUpIdentityProvider();
|
||||
|
||||
Map<String, String> config = result.getConfig();
|
||||
|
||||
config.put("validateSignature", "true");
|
||||
config.put("wantAuthnRequestsSigned", "true");
|
||||
config.put("signingCertificate", IDP_SAML_SIGN_CERT);
|
||||
|
||||
return result;
|
||||
protected BrokerConfiguration getBrokerConfiguration() {
|
||||
return KcSamlSignedBrokerConfiguration.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue