- */
-public class MultiTenantResolver implements KeycloakConfigResolver {
-
- @Override
- public KeycloakDeployment resolve(HttpFacade.Request request) {
-
- String path = request.getURI();
- int multitenantIndex = path.indexOf("multi-tenant/");
- if (multitenantIndex == -1) {
- throw new IllegalStateException("Not able to resolve realm from the request path!");
- }
-
- String realm = path.substring(path.indexOf("multi-tenant/")).split("/")[1];
- if (realm.contains("?")) {
- realm = realm.split("\\?")[0];
- }
-
- InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("/" + realm + "-keycloak.json");
-
- if (is == null) {
- throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak.json");
- }
-
- KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(is);
- return deployment;
- }
-
-}
diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java
deleted file mode 100644
index 2425430445..0000000000
--- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/OfflineTokenServlet.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.keycloak.testsuite.adapter.servlet;
-
-import org.keycloak.OAuth2Constants;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.UriBuilder;
-import java.io.IOException;
-
-/**
- * @author Marek Posolda
- */
-public class OfflineTokenServlet extends AbstractShowTokensServlet {
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- if (req.getRequestURI().endsWith("logout")) {
-
- UriBuilder redirectUriBuilder = UriBuilder.fromUri(ServletTestUtils.getUrlBase() + "/offline-client");
- if (req.getParameter(OAuth2Constants.SCOPE) != null) {
- redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, req.getParameter(OAuth2Constants.SCOPE));
- }
- String redirectUri = redirectUriBuilder.build().toString();
-
- String serverLogoutRedirect = UriBuilder.fromUri(ServletTestUtils.getAuthServerUrlBase() + "/auth/realms/test/protocol/openid-connect/logout")
- .queryParam("redirect_uri", redirectUri)
- .build().toString();
-
- resp.sendRedirect(serverLogoutRedirect);
- return;
- }
-
- StringBuilder response = new StringBuilder("Offline token servlet");
-
- String tokens = renderTokens(req);
- response = response.append(tokens);
-
- response.append("
");
- resp.getWriter().println(response.toString());
- }
-}
-
diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SerializationServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SerializationServlet.java
deleted file mode 100644
index eef704f86f..0000000000
--- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SerializationServlet.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.servlet;
-
-import org.keycloak.KeycloakPrincipal;
-import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
-
-import javax.servlet.annotation.WebServlet;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
-import java.io.PrintWriter;
-
-/**
- * @author mhajas
- */
-@WebServlet("/serialization-servlet")
-public class SerializationServlet extends HttpServlet {
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- PrintWriter pw = resp.getWriter();
- // Serialize
- ByteArrayOutputStream bso = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bso);
- oos.writeObject(req.getUserPrincipal());
- oos.close();
-
- // Deserialize
- byte[] bytes = bso.toByteArray();
- ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bis) {
- @Override
- public Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
- try {
- return Class.forName(desc.getName(), true, SerializationServlet.class.getClassLoader());
- } catch (Exception e) { }
-
- // Fall back (e.g. for primClasses)
- return super.resolveClass(desc);
- }
- };
-
- KeycloakPrincipal principal;
- try {
- principal = (KeycloakPrincipal) ois.readObject();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- pw.write("Deserialization failed");
- return;
- }
-
- KeycloakSecurityContext ctx = principal.getKeycloakSecurityContext();
- if (!(ctx instanceof RefreshableKeycloakSecurityContext)) {
- pw.write("Context was not instance of RefreshableKeycloakSecurityContext");
- }
-
- pw.write("Serialization/Deserialization was successful");
- }
-}
diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/TokenMinTTLServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/TokenMinTTLServlet.java
deleted file mode 100644
index 7d266bc887..0000000000
--- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/TokenMinTTLServlet.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.servlet;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * @author Marek Posolda
- */
-public class TokenMinTTLServlet extends AbstractShowTokensServlet {
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- StringBuilder response = new StringBuilder("Token Min TTL Servlet");
-
- String tokens = renderTokens(req);
- response = response.append(tokens);
-
- response.append("
");
- resp.getWriter().println(response.toString());
- }
-
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MutualTLSUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MutualTLSUtils.java
index 2796742653..a4ea9ec043 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MutualTLSUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MutualTLSUtils.java
@@ -1,18 +1,24 @@
package org.keycloak.testsuite.util;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Enumeration;
-
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response;
-
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.keycloak.common.util.Base64Url;
@@ -66,7 +72,7 @@ public class MutualTLSUtils {
try {
keystore = KeystoreUtil.loadKeyStore(keyStorePath, keyStorePassword);
} catch (Exception e) {
- e.printStackTrace();
+ throw new RuntimeException(e);
}
}
@@ -76,20 +82,33 @@ public class MutualTLSUtils {
try {
truststore = KeystoreUtil.loadKeyStore(trustStorePath, trustStorePassword);
} catch(Exception e) {
- e.printStackTrace();
+ throw new RuntimeException(e);
}
}
- if (keystore != null || truststore != null)
- return (CloseableHttpClient) new org.keycloak.adapters.HttpClientBuilder()
- .keyStore(keystore, keyStorePassword)
- .trustStore(truststore)
- .hostnameVerification(org.keycloak.adapters.HttpClientBuilder.HostnameVerificationPolicy.ANY)
- .build();
+ if (keystore != null || truststore != null) {
+ return newCloseableHttpClientSSL(keystore, keyStorePassword, truststore);
+ }
return HttpClientBuilder.create().build();
}
+ public static CloseableHttpClient newCloseableHttpClientSSL(KeyStore keystore, String keyStorePassword, KeyStore truststore) {
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmfactory.init(keystore, keyStorePassword.toCharArray());
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(truststore);
+ sslContext.init(kmfactory.getKeyManagers(), tmf.getTrustManagers(), null);
+ SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
+
+ return HttpClientBuilder.create().setSSLSocketFactory(sf).build();
+ } catch (NoSuchAlgorithmException|KeyStoreException|KeyManagementException|UnrecoverableKeyException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public static String getThumbprintFromDefaultClientCert() throws KeyStoreException, CertificateEncodingException {
return getThumbprintFromClientCert(DEFAULT_KEYSTOREPATH, DEFAULT_KEYSTOREPASSWORD);
}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
index 94861ea35d..cb5901161f 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
@@ -41,7 +41,6 @@ import org.keycloak.OAuth2Constants;
import org.keycloak.TokenVerifier;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.VerificationException;
-import org.keycloak.common.util.KeystoreUtil;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.crypto.Algorithm;
import org.keycloak.crypto.AsymmetricSignatureSignerContext;
@@ -92,7 +91,6 @@ import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
-import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Collections;
@@ -441,26 +439,7 @@ public class OAuthClient {
public static CloseableHttpClient newCloseableHttpClientSSL(String keyStorePath,
String keyStorePassword, String trustStorePath, String trustStorePassword) {
- KeyStore keystore = null;
- // load the keystore containing the client certificate - keystore type is probably jks or pkcs12
- try {
- keystore = KeystoreUtil.loadKeyStore(keyStorePath, keyStorePassword);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- // load the truststore
- KeyStore truststore = null;
- try {
- truststore = KeystoreUtil.loadKeyStore(trustStorePath, trustStorePassword);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return (CloseableHttpClient) new org.keycloak.adapters.HttpClientBuilder()
- .keyStore(keystore, keyStorePassword)
- .trustStore(truststore)
- .hostnameVerification(org.keycloak.adapters.HttpClientBuilder.HostnameVerificationPolicy.ANY)
- .build();
+ return MutualTLSUtils.newCloseableHttpClient(keyStorePath, keyStorePassword, trustStorePath, trustStorePassword);
}
public CloseableHttpResponse doPreflightRequest() {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractBaseServletAuthzAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractBaseServletAuthzAdapterTest.java
deleted file mode 100644
index 5a0f1d999e..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractBaseServletAuthzAdapterTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2018 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.authz.example;
-
-import org.jboss.arquillian.container.test.api.Deployer;
-import org.jboss.arquillian.graphene.page.Page;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.junit.BeforeClass;
-import org.keycloak.admin.client.resource.AuthorizationResource;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.authorization.PolicyRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
-import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
-import org.keycloak.testsuite.ProfileAssume;
-import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
-import org.keycloak.testsuite.pages.InfoPage;
-import org.keycloak.testsuite.pages.LogoutConfirmPage;
-import org.keycloak.testsuite.util.UIUtils;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
-
-import jakarta.ws.rs.core.Response;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-import static org.junit.Assert.assertFalse;
-import static org.keycloak.common.Profile.Feature.AUTHORIZATION;
-import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
-import static org.keycloak.testsuite.utils.io.IOUtil.loadJson;
-import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm;
-import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
-
-/**
- * @author Pedro Igor
- */
-public abstract class AbstractBaseServletAuthzAdapterTest extends AbstractExampleAdapterTest {
-
- protected static final String REALM_NAME = "servlet-authz";
- protected static final String RESOURCE_SERVER_ID = "servlet-authz-app";
-
- @ArquillianResource
- private Deployer deployer;
-
- @Page
- protected LogoutConfirmPage logoutConfirmPage;
-
- @Page
- protected InfoPage infoPage;
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @Override
- public void addAdapterTestRealms(List testRealms) {
- testRealms.add(
- loadRealm(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/servlet-authz-realm.json")));
- }
-
- protected void performTests(ExceptionRunnable assertion) {
- performTests(() -> importResourceServerSettings(), assertion);
- }
-
- protected void performTests(ExceptionRunnable beforeDeploy, ExceptionRunnable assertion) {
- try {
- beforeDeploy.run();
- deployer.deploy(RESOURCE_SERVER_ID);
- assertion.run();
- } catch (FileNotFoundException cause) {
- throw new RuntimeException("Failed to import authorization settings", cause);
- } catch (Exception cause) {
- throw new RuntimeException("Error while executing tests", cause);
- } finally {
- deployer.undeploy(RESOURCE_SERVER_ID);
- }
- }
-
- protected boolean hasLink(String text) {
- return getLink(text) != null;
- }
-
- protected boolean hasText(String text) {
- return this.driver.getPageSource().contains(text);
- }
-
- protected WebElement getLink(String text) {
- return this.driver.findElement(By.xpath("//a[text() = '" + text + "']"));
- }
-
- protected void importResourceServerSettings() throws FileNotFoundException {
- getAuthorizationResource().importSettings(loadJson(new FileInputStream(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/servlet-authz-app-authz-service.json")), ResourceServerRepresentation.class));
- }
-
- protected AuthorizationResource getAuthorizationResource() {
- return getClientResource(RESOURCE_SERVER_ID).authorization();
- }
-
- protected ClientResource getClientResource(String clientId) {
- ClientsResource clients = this.realmsResouce().realm(REALM_NAME).clients();
- ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
- return clients.get(resourceServer.getId());
- }
-
- private void logOut() {
- navigateTo();
- UIUtils.clickLink(driver.findElement(By.xpath("//a[text() = 'Sign Out']")));
-
- logoutConfirmPage.assertCurrent();
- logoutConfirmPage.confirmLogout();
- infoPage.assertCurrent();
- }
-
-
- protected void login(String username, String password) {
- try {
- navigateTo();
- if (this.driver.getCurrentUrl().startsWith(getResourceServerUrl().toString())) {
- logOut();
- navigateTo();
- }
-
- this.loginPage.form().login(username, password);
- } catch (Exception cause) {
- throw new RuntimeException("Login failed", cause);
- }
- }
-
- protected void navigateTo() {
- this.driver.navigate().to(getResourceServerUrl() + "/");
- waitForPageToLoad();
- }
-
- protected void assertWasDenied() {
- waitUntilElement(By.tagName("body")).text().contains("You can not access this resource.");
- }
-
- protected void assertWasNotDenied() {
- waitUntilElement(By.tagName("body")).text().not().contains("You can not access this resource.");
- }
-
- protected URL getResourceServerUrl() {
- try {
- return new URL(this.appServerContextRootPage + "/" + RESOURCE_SERVER_ID);
- } catch (MalformedURLException e) {
- throw new RuntimeException("Could not obtain resource server url.", e);
- }
- }
-
- protected void navigateToDynamicMenuPage() {
- navigateTo();
- UIUtils.clickLink(getLink("Dynamic Menu"));
- }
-
- protected void navigateToUserPremiumPage() {
- navigateTo();
- UIUtils.clickLink(getLink("User Premium"));
- }
-
- protected void navigateToAdminPage() {
- navigateTo();
- UIUtils.clickLink(getLink("Administration"));
- }
-
- protected void updatePermissionPolicies(String permissionName, String... policyNames) {
- for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
- if (permissionName.equalsIgnoreCase(policy.getName())) {
- StringBuilder policies = new StringBuilder("[");
-
- for (String policyName : policyNames) {
- if (policies.length() > 1) {
- policies.append(",");
- }
- policies.append("\"").append(policyName).append("\"");
-
- }
-
- policies.append("]");
-
- policy.getConfig().put("applyPolicies", policies.toString());
- getAuthorizationResource().policies().policy(policy.getId()).update(policy);
- }
- }
- }
-
- protected void createUserPolicy(String name, String... userNames) {
- UserPolicyRepresentation policy = new UserPolicyRepresentation();
-
- policy.setName(name);
-
- for (String userName : userNames) {
- policy.addUser(userName);
- }
-
- assertFalse(policy.getUsers().isEmpty());
-
- Response response = getAuthorizationResource().policies().user().create(policy);
- response.close();
- }
-
- protected interface ExceptionRunnable {
- void run() throws Exception;
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractServletAuthzAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractServletAuthzAdapterTest.java
deleted file mode 100644
index bac42f8940..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractServletAuthzAdapterTest.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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.authz.example;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.ClientPoliciesResource;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.admin.client.resource.ResourcesResource;
-import org.keycloak.admin.client.resource.RolePoliciesResource;
-import org.keycloak.admin.client.resource.RoleScopeResource;
-import org.keycloak.admin.client.resource.RolesResource;
-import org.keycloak.admin.client.resource.UserResource;
-import org.keycloak.admin.client.resource.UsersResource;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
-import org.keycloak.testsuite.util.WaitUtils;
-import org.openqa.selenium.By;
-
-import jakarta.ws.rs.core.Response;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
-
-/**
- * @author Pedro Igor
- */
-public abstract class AbstractServletAuthzAdapterTest extends AbstractBaseServletAuthzAdapterTest {
-
- @Test
- public void testCanNotAccessWhenEnforcing() throws Exception {
- performTests(() -> {
- importResourceServerSettings();
- ResourcesResource resources = getAuthorizationResource().resources();
- ResourceRepresentation resource = resources.findByName("Protected Resource").get(0);
-
- resource.setUri("/index.jsp");
-
- resources.resource(resource.getId()).update(resource);
- }, () -> {
- login("jdoe", "jdoe");
- driver.navigate().to(getResourceServerUrl().toString() + "/enforcing/resource");
- assertWasDenied();
- });
- }
-
- @Test
- public void testRegularUserPermissions() throws Exception {
- performTests(() -> {
- login("alice", "alice");
- assertWasNotDenied();
- assertTrue(hasLink("User Premium"));
- assertTrue(hasLink("Administration"));
- assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
- assertFalse(hasText("urn:servlet-authz:page:main:actionForAdmin"));
- assertFalse(hasText("urn:servlet-authz:page:main:actionForPremiumUser"));
-
- navigateToDynamicMenuPage();
- assertTrue(hasText("Do user thing"));
- assertFalse(hasText("Do user premium thing"));
- assertFalse(hasText("Do administration thing"));
-
- navigateToUserPremiumPage();
- assertWasDenied();
-
- navigateToAdminPage();
- assertWasDenied();
- });
- }
-
- @Test
- public void testUserPremiumPermissions() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
- assertWasNotDenied();
- assertTrue(hasLink("User Premium"));
- assertTrue(hasLink("Administration"));
- assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
- assertTrue(hasText("urn:servlet-authz:page:main:actionForPremiumUser"));
- assertFalse(hasText("urn:servlet-authz:page:main:actionForAdmin"));
-
- navigateToDynamicMenuPage();
- assertTrue(hasText("Do user thing"));
- assertTrue(hasText("Do user premium thing"));
- assertFalse(hasText("Do administration thing"));
-
- navigateToUserPremiumPage();
- assertWasNotDenied();
-
- navigateToAdminPage();
- assertWasDenied();
- });
- }
-
- @Test
- public void testAdminPermissions() throws Exception {
- performTests(() -> {
- login("admin", "admin");
- assertWasNotDenied();
- assertTrue(hasLink("User Premium"));
- assertTrue(hasLink("Administration"));
- assertTrue(hasText("urn:servlet-authz:page:main:actionForUser"));
- assertTrue(hasText("urn:servlet-authz:page:main:actionForAdmin"));
- assertFalse(hasText("urn:servlet-authz:page:main:actionForPremiumUser"));
-
- navigateToDynamicMenuPage();
- assertTrue(hasText("Do user thing"));
- assertTrue(hasText("Do administration thing"));
- assertFalse(hasText("Do user premium thing"));
-
- navigateToUserPremiumPage();
- assertWasDenied();
-
- navigateToAdminPage();
- assertWasNotDenied();
- });
- }
-
- @Test
- public void testGrantPremiumAccessToUser() throws Exception {
- performTests(() -> {
- login("alice", "alice");
- assertWasNotDenied();
-
- navigateToUserPremiumPage();
- assertWasDenied();
-
- updatePermissionPolicies("Premium Resource Permission", "Any User Policy");
-
- login("alice", "alice");
-
- navigateToUserPremiumPage();
- assertWasNotDenied();
-
- updatePermissionPolicies("Premium Resource Permission", "Only Premium User Policy");
-
- login("alice", "alice");
-
- navigateToUserPremiumPage();
- assertWasDenied();
-
- createUserPolicy("Temporary Premium Access Policy", "alice");
-
- updatePermissionPolicies("Premium Resource Permission", "Temporary Premium Access Policy");
-
- login("alice", "alice");
-
- navigateToUserPremiumPage();
- assertWasNotDenied();
- });
- }
-
- @Test
- public void testGrantAdministrativePermissions() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
-
- navigateToAdminPage();
- assertWasDenied();
-
- RealmResource realmResource = realmsResouce().realm(REALM_NAME);
- UsersResource usersResource = realmResource.users();
- List users = usersResource.search("jdoe", null, null, null, null, null);
-
- assertFalse(users.isEmpty());
-
- UserResource userResource = usersResource.get(users.get(0).getId());
-
- RoleRepresentation adminRole = realmResource.roles().get("admin").toRepresentation();
- userResource.roles().realmLevel().add(Arrays.asList(adminRole));
-
- login("jdoe", "jdoe");
-
- navigateToAdminPage();
- assertWasNotDenied();
- });
- }
-
- //KEYCLOAK-3830
- @Test
- @Ignore // Ignored because: KEYCLOAK-7941
- public void testAccessPublicResource() throws Exception {
- performTests(() -> {
- driver.navigate().to(getResourceServerUrl() + "/public-html.html");
- WaitUtils.waitForPageToLoad();
- assertTrue(hasText("This is public resource that should be accessible without login."));
- });
- }
-
- @Test
- public void testRequiredRole() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
- navigateToUserPremiumPage();
- assertWasNotDenied();
-
- RolesResource rolesResource = getClientResource(RESOURCE_SERVER_ID).roles();
-
- rolesResource.create(new RoleRepresentation("required-role", "", false));
-
- RolePolicyRepresentation policy = new RolePolicyRepresentation();
-
- policy.setName("Required Role Policy");
- policy.addRole("user_premium", false);
- policy.addRole(RESOURCE_SERVER_ID + "/required-role", false);
-
- RolePoliciesResource rolePolicy = getAuthorizationResource().policies().role();
-
- rolePolicy.create(policy);
- policy = rolePolicy.findByName(policy.getName());
-
- updatePermissionPolicies("Premium Resource Permission", policy.getName());
-
- login("jdoe", "jdoe");
- navigateToUserPremiumPage();
- assertWasNotDenied();
-
- policy.getRoles().clear();
- policy.addRole("user_premium", false);
- policy.addRole(RESOURCE_SERVER_ID + "/required-role", true);
-
- rolePolicy.findById(policy.getId()).update(policy);
-
- login("jdoe", "jdoe");
- navigateToUserPremiumPage();
- assertWasDenied();
-
- UsersResource users = realmsResouce().realm(REALM_NAME).users();
- UserRepresentation user = users.search("jdoe").get(0);
-
- RoleScopeResource roleScopeResource = users.get(user.getId()).roles().clientLevel(getClientResource(RESOURCE_SERVER_ID).toRepresentation().getId());
- RoleRepresentation requiredRole = rolesResource.get("required-role").toRepresentation();
- roleScopeResource.add(Arrays.asList(requiredRole));
-
- login("jdoe", "jdoe");
- navigateToUserPremiumPage();
- assertWasNotDenied();
-
- policy.getRoles().clear();
- policy.addRole("user_premium", false);
- policy.addRole(RESOURCE_SERVER_ID + "/required-role", false);
-
- rolePolicy.findById(policy.getId()).update(policy);
-
- login("jdoe", "jdoe");
- navigateToUserPremiumPage();
- assertWasNotDenied();
-
- roleScopeResource.remove(Arrays.asList(requiredRole));
-
- login("jdoe", "jdoe");
- navigateToUserPremiumPage();
- assertWasNotDenied();
- });
- }
-
- @Test
- public void testOnlySpecificClient() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
- assertWasNotDenied();
-
- ClientPolicyRepresentation policy = new ClientPolicyRepresentation();
-
- policy.setName("Only Client Policy");
- policy.addClient("admin-cli");
-
- ClientPoliciesResource policyResource = getAuthorizationResource().policies().client();
- Response response = policyResource.create(policy);
- response.close();
- policy = policyResource.findByName(policy.getName());
-
- updatePermissionPolicies("Protected Resource Permission", policy.getName());
-
- login("jdoe", "jdoe");
- assertWasDenied();
-
- policy.addClient("servlet-authz-app");
- policyResource.findById(policy.getId()).update(policy);
-
- login("jdoe", "jdoe");
- assertWasNotDenied();
- });
- }
-
- @Test
- public void testAccessResourceWithAnyScope() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
- driver.navigate().to(getResourceServerUrl() + "/protected/scopes.jsp");
- WaitUtils.waitForPageToLoad();
- assertTrue(hasText("Granted"));
- });
- }
-
- @Test
- public void testMultipleURLsForResourceRealmConfig() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource1/index1.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource1 index1.jsp");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource1/index2.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource1 index2.jsp");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/pattern1/page.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource2/pattern1");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/pattern2/page.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource2/pattern2");
-
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/test.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("keycloak-7269/test");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/test.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("keycloak-7269/sub-resource2/test");
-
- updatePermissionPolicies("Permission for multiple url resource", "Deny Policy");
- login("jdoe", "jdoe");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource1/index1.jsp");
- waitUntilElement(By.tagName("h2")).text().not().contains("sub-resource1 index1.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("You can not access this resource.");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource1/index2.jsp");
- waitUntilElement(By.tagName("h2")).text().not().contains("sub-resource1 index2.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("You can not access this resource.");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/pattern1/page.jsp");
- waitUntilElement(By.tagName("h2")).text().not().contains("sub-resource2/pattern1");
- waitUntilElement(By.tagName("h2")).text().contains("You can not access this resource.");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/pattern2/page.jsp");
- waitUntilElement(By.tagName("h2")).text().not().contains("sub-resource2/pattern2");
- waitUntilElement(By.tagName("h2")).text().contains("You can not access this resource.");
-
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/test.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("keycloak-7269/test");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/test.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("keycloak-7269/sub-resource2/test");
-
- updatePermissionPolicies("Permission for multiple url resource", "All Users Policy");
- login("jdoe", "jdoe");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource1/index1.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource1 index1.jsp");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource1/index2.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource1 index2.jsp");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/pattern1/page.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource2/pattern1");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/pattern2/page.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("sub-resource2/pattern2");
-
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/test.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("keycloak-7269/test");
- driver.navigate().to(getResourceServerUrl() + "/keycloak-7269/sub-resource2/test.jsp");
- waitUntilElement(By.tagName("h2")).text().contains("keycloak-7269/sub-resource2/test");
- });
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractServletPolicyEnforcerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractServletPolicyEnforcerTest.java
deleted file mode 100644
index 37c1217f0e..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/AbstractServletPolicyEnforcerTest.java
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * 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.authz.example;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.common.Profile.Feature.AUTHORIZATION;
-import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
-import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-import org.jboss.arquillian.container.test.api.Deployer;
-import org.jboss.arquillian.graphene.page.Page;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.AuthorizationResource;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.admin.client.resource.ResourcePermissionsResource;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-import org.keycloak.testsuite.ProfileAssume;
-import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
-import org.keycloak.testsuite.pages.InfoPage;
-import org.keycloak.testsuite.pages.LogoutConfirmPage;
-import org.keycloak.testsuite.util.ServerURLs;
-import org.keycloak.testsuite.util.UIUtils;
-import org.openqa.selenium.By;
-
-/**
- * @author Pedro Igor
- */
-public class AbstractServletPolicyEnforcerTest extends AbstractExampleAdapterTest {
-
- protected static final String REALM_NAME = "servlet-policy-enforcer-authz";
- protected static final String RESOURCE_SERVER_ID = "servlet-policy-enforcer";
-
- @ArquillianResource
- private Deployer deployer;
-
- @Page
- protected LogoutConfirmPage logoutConfirmPage;
-
- @Page
- protected InfoPage infoPage;
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @Override
- public void addAdapterTestRealms(List testRealms) {
- testRealms.add(
- loadRealm(new File(TEST_APPS_HOME_DIR + "/servlet-policy-enforcer/servlet-policy-enforcer-authz-realm.json")));
- }
-
- @Test
- public void testPattern1() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/resource/a/b");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 1 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/resource/a/b");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 1 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/resource/a/b");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern2() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/a/resource-a");
- assertFalse(wasDenied());
- navigateTo("/b/resource-a");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 2 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/a/resource-a");
- assertTrue(wasDenied());
- navigateTo("/b/resource-a");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 2 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/b/resource-a");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern3() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/a/resource-b");
- assertFalse(wasDenied());
- navigateTo("/b/resource-b");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 3 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/a/resource-b");
- assertTrue(wasDenied());
- navigateTo("/b/resource-b");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 3 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/b/resource-b");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 2 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/b/resource-a");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 3 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/a/resource-b");
- assertTrue(wasDenied());
- navigateTo("/b/resource-a");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern4() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/resource-c");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 4 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/resource-c");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 4 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/resource-c");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern5() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/a/a/resource-d");
- assertFalse(wasDenied());
- navigateTo("/resource/b/resource-d");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 5 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/a/a/resource-d");
- assertTrue(wasDenied());
- navigateTo("/a/b/resource-d");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 5 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/a/b/resource-d");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern6() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/resource/a");
- assertFalse(wasDenied());
- navigateTo("/resource/b");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 6 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/resource/a");
- assertTrue(wasDenied());
- navigateTo("/resource/b");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 6 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/resource/b");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern7() throws Exception {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/resource/a/f/b");
- assertFalse(wasDenied());
- navigateTo("/resource/c/f/d");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 7 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/resource/a/f/b");
- assertTrue(wasDenied());
- navigateTo("/resource/c/f/d");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 7 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/resource/c/f/d");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern8() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/resource");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 8 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/resource");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 8 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/resource");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern9() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/file/*.suffix");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 9 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/file/*.suffix");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 9 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/file/*.suffix");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern10() {
- performTests(() -> {
- login("alice", "alice");
-
- navigateTo("/resource/a/i/b/c/d/e");
- assertFalse(wasDenied());
- navigateTo("/resource/a/i/b/c/");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 10 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/resource/a/i/b/c/d/e");
- assertTrue(wasDenied());
- navigateTo("/resource/a/i/b/c/d");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 10 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/resource/a/i/b/c/d");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPattern11UsingResourceInstancePermission() {
- performTests(() -> {
- login("alice", "alice");
- navigateTo("/api/v1/resource-a");
- assertFalse(wasDenied());
- navigateTo("/api/v1/resource-b");
- assertFalse(wasDenied());
-
- ResourceRepresentation resource = new ResourceRepresentation("/api/v1/resource-c");
-
- resource.setUri(resource.getName());
-
- getAuthorizationResource().resources().create(resource);
-
- createResourcePermission(resource.getName() + " permission", resource.getName(), "Default Policy");
-
- login("alice", "alice");
- navigateTo(resource.getUri());
- assertFalse(wasDenied());
-
- updatePermissionPolicies(resource.getName() + " permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo(resource.getUri());
- assertTrue(wasDenied());
-
- updatePermissionPolicies(resource.getName() + " permission", "Default Policy");
-
- login("alice", "alice");
- navigateTo(resource.getUri());
- assertFalse(wasDenied());
-
- navigateTo("/api/v1");
- assertTrue(wasDenied());
- navigateTo("/api/v1/");
- assertTrue(wasDenied());
- navigateTo("/api");
- assertTrue(wasDenied());
- navigateTo("/api/");
- assertTrue(wasDenied());
- });
- }
-
- @Test
- public void testPathWithPatternSlashAllAndResourceInstance() {
- performTests(() -> {
- ResourceRepresentation resource = new ResourceRepresentation("Pattern 15 Instance");
-
- resource.setType("pattern-15");
- resource.setUri("/keycloak-7148/1");
- resource.setOwner("alice");
-
- getAuthorizationResource().resources().create(resource).close();
-
- login("alice", "alice");
- navigateTo("/keycloak-7148/1");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7148/1/sub-a/2");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7148/1/sub-a");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7148/1/sub-a/2/sub-b");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 15 Permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo("/keycloak-7148/1");
- assertTrue(wasDenied());
- navigateTo("/keycloak-7148/1/sub-a/2");
- assertTrue(wasDenied());
- navigateTo("/keycloak-7148/1/sub-a");
- assertTrue(wasDenied());
- navigateTo("/keycloak-7148/1/sub-a/2/sub-b");
- assertTrue(wasDenied());
-
- // does not exist
- navigateTo("/keycloak-7148/2");
- assertTrue(wasDenied());
- });
- }
-
- @Test
- public void testPriorityOfURIForResource() {
- performTests(() -> {
- login("alice", "alice");
- navigateTo("/realm_uri");
- assertTrue(wasDenied());
- navigateTo("/keycloak_json_uri");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 12 Permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo("/realm_uri");
- assertTrue(wasDenied());
- navigateTo("/keycloak_json_uri");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 12 Permission", "Default Policy");
-
- login("alice", "alice");
- navigateTo("/realm_uri");
- assertTrue(wasDenied());
- navigateTo("/keycloak_json_uri");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testPathOrderWithAllPaths() {
- performTests(() -> {
- login("alice", "alice");
- navigateTo("/keycloak-6623");
- assertFalse(wasDenied());
- navigateTo("/keycloak-6623/sub-resource");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 13 Permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo("/keycloak-6623");
- assertTrue(wasDenied());
- navigateTo("/keycloak-6623/sub-resource");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 14 Permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo("/keycloak-6623");
- assertTrue(wasDenied());
- navigateTo("/keycloak-6623/sub-resource/resource");
- assertTrue(wasDenied());
- });
- }
-
- @Test
- public void testMultipleUriForResourceJSONConfig() {
- performTests(() -> {
- login("alice", "alice");
- navigateTo("/keycloak-7269/sub-resource1");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7269/sub-resource1/whatever/specialSuffix");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7269/sub-resource2");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7269/sub-resource2/w/h/a/t/e/v/e/r");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 16 Permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo("/keycloak-7269/sub-resource1");
- assertTrue(wasDenied());
- navigateTo("/keycloak-7269/sub-resource1/whatever/specialSuffix");
- assertTrue(wasDenied());
- navigateTo("/keycloak-7269/sub-resource2");
- assertTrue(wasDenied());
- navigateTo("/keycloak-7269/sub-resource2/w/h/a/t/e/v/e/r");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 16 Permission", "Default Policy");
- navigateTo("/keycloak-7269/sub-resource1");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7269/sub-resource1/whatever/specialSuffix");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7269/sub-resource2");
- assertFalse(wasDenied());
- navigateTo("/keycloak-7269/sub-resource2/w/h/a/t/e/v/e/r");
- assertFalse(wasDenied());
- });
- }
-
- @Test
- public void testOverloadedTemplateUri() {
- performTests(() -> {
- login("alice", "alice");
- navigateTo("/keycloak-8823/resource/v1/subresource/123/entities");
- assertFalse(wasDenied());
- navigateTo("/keycloak-8823/resource/v1/subresource/123/someother");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 17 Entities Permission", "Deny Policy");
-
- login("alice", "alice");
- navigateTo("/keycloak-8823/resource/v1/subresource/123/entities");
- assertTrue(wasDenied());
- navigateTo("/keycloak-8823/resource/v1/subresource/123/someother");
- assertFalse(wasDenied());
-
- updatePermissionPolicies("Pattern 17 Entities Permission", "Default Policy");
- updatePermissionPolicies("Pattern 17 Permission", "Deny Policy");
- login("alice", "alice");
- navigateTo("/keycloak-8823/resource/v1/subresource/123/entities");
- assertFalse(wasDenied());
- navigateTo("/keycloak-8823/resource/v1/subresource/123/someother");
- assertTrue(wasDenied());
-
- updatePermissionPolicies("Pattern 17 Entities Permission", "Default Policy");
- updatePermissionPolicies("Pattern 17 Permission", "Default Policy");
- login("alice", "alice");
- navigateTo("/keycloak-8823/resource/v1/subresource/123/entities");
- assertFalse(wasDenied());
- navigateTo("/keycloak-8823/resource/v1/subresource/123/someother");
- assertFalse(wasDenied());
- });
- }
-
- private void navigateTo(String path) {
- this.driver.navigate().to(getResourceServerUrl() + path);
- }
-
- private void performTests(ExceptionRunnable assertion) {
- performTests(() -> {}, assertion);
- }
-
- private void performTests(ExceptionRunnable beforeDeploy, ExceptionRunnable assertion) {
- try {
- beforeDeploy.run();
- deployer.deploy(RESOURCE_SERVER_ID);
- assertion.run();
- } catch (FileNotFoundException cause) {
- throw new RuntimeException("Failed to import authorization settings", cause);
- } catch (Exception cause) {
- throw new RuntimeException("Error while executing tests", cause);
- } finally {
- deployer.undeploy(RESOURCE_SERVER_ID);
- }
- }
-
- private AuthorizationResource getAuthorizationResource() {
- return getClientResource(RESOURCE_SERVER_ID).authorization();
- }
-
- private ClientResource getClientResource(String clientId) {
- ClientsResource clients = this.realmsResouce().realm(REALM_NAME).clients();
- ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
- return clients.get(resourceServer.getId());
- }
-
- private void logOut() {
- navigateTo();
- UIUtils.clickLink(driver.findElement(By.xpath("//a[text() = 'Sign Out']")));
-
- logoutConfirmPage.assertCurrent();
- logoutConfirmPage.confirmLogout();
- infoPage.assertCurrent();
- }
-
- private void login(String username, String password) {
- try {
- navigateTo();
- if (this.driver.getCurrentUrl().startsWith(getResourceServerUrl().toString())) {
- logOut();
- navigateTo();
- }
- this.loginPage.form().login(username, password);
- navigateTo();
- assertFalse(wasDenied());
- } catch (Exception cause) {
- throw new RuntimeException("Login failed", cause);
- }
- }
-
- private void navigateTo() {
- this.driver.navigate().to(getResourceServerUrl() + "/");
- waitForPageToLoad();
- }
-
- private boolean wasDenied() {
- return this.driver.getPageSource().contains("You can not access this resource");
- }
-
- private URL getResourceServerUrl() {
- try {
- return new URL(ServerURLs.getAppServerContextRoot() + "/" + RESOURCE_SERVER_ID);
- } catch (MalformedURLException e) {
- throw new RuntimeException("Could not obtain resource server url.", e);
- }
- }
-
- private void updatePermissionPolicies(String permissionName, String... policyNames) {
- ResourcePermissionsResource permissions = getAuthorizationResource().permissions().resource();
- ResourcePermissionRepresentation permission = permissions.findByName(permissionName);
-
- permission.addPolicy(policyNames);
-
- permissions.findById(permission.getId()).update(permission);
- }
-
- private void createResourcePermission(String name, String resourceName, String... policyNames) {
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName(name);
- permission.addResource(resourceName);
- permission.addPolicy(policyNames);
-
- getAuthorizationResource().permissions().resource().create(permission);
- }
-
- private interface ExceptionRunnable {
- void run() throws Exception;
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/DefaultAuthzConfigAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/DefaultAuthzConfigAdapterTest.java
deleted file mode 100644
index f2c078c525..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/DefaultAuthzConfigAdapterTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.authz.example;
-
-import org.jboss.arquillian.container.test.api.Deployer;
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.AuthorizationResource;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.authorization.PolicyRepresentation;
-import org.keycloak.testsuite.ProfileAssume;
-import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.util.ServerURLs;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.common.Profile.Feature.AUTHORIZATION;
-import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class DefaultAuthzConfigAdapterTest extends AbstractExampleAdapterTest {
-
- private static final String REALM_NAME = "hello-world-authz";
- private static final String RESOURCE_SERVER_ID = "hello-world-authz-service";
-
- @ArquillianResource
- private Deployer deployer;
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @Override
- public void addAdapterTestRealms(List testRealms) {
- testRealms.add(
- loadRealm(new File(TEST_APPS_HOME_DIR + "/hello-world-authz-service/hello-world-authz-realm.json")));
- }
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID);
- }
-
- @Test
- public void testDefaultAuthzConfig() throws Exception {
- try {
- configureAuthorizationServices();
- this.deployer.deploy(RESOURCE_SERVER_ID);
-
- login();
-
- assertTrue(this.driver.getPageSource().contains("Your permissions are"));
- assertTrue(this.driver.getPageSource().contains("Default Resource"));
-
- boolean hasDefaultPermission = false;
- boolean hasDefaultPolicy = false;
-
- for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
- if ("Default Policy".equals(policy.getName())) {
- hasDefaultPolicy = true;
- }
- if ("Default Permission".equals(policy.getName())) {
- hasDefaultPermission = true;
- }
- }
-
- assertTrue(hasDefaultPermission);
- assertTrue(hasDefaultPolicy);
- } finally {
- this.deployer.undeploy(RESOURCE_SERVER_ID);
- }
- }
-
- private void login() throws MalformedURLException {
- this.driver.navigate().to(getResourceServerUrl() + "/");
- this.loginPage.form().login("alice", "alice");
- }
-
- private URL getResourceServerUrl() throws MalformedURLException {
- return new URL(ServerURLs.getAppServerContextRoot() + "/" + RESOURCE_SERVER_ID);
- }
-
- private void configureAuthorizationServices() {
- ClientsResource clients = realmsResouce().realm(REALM_NAME).clients();
- ClientRepresentation client = clients.findByClientId(RESOURCE_SERVER_ID).get(0);
-
- client.setAuthorizationServicesEnabled(false);
-
- // disables authorization services and remove authorization configuration from the client app
- clients.get(client.getId()).update(client);
-
- client.setAuthorizationServicesEnabled(true);
-
- // enable authorization services in order to generate the default config and continue with tests
- clients.get(client.getId()).update(client);
- }
-
- private AuthorizationResource getAuthorizationResource() throws FileNotFoundException {
- return getClientResource(RESOURCE_SERVER_ID).authorization();
- }
-
- private ClientResource getClientResource(String clientId) {
- ClientsResource clients = this.realmsResouce().realm(REALM_NAME).clients();
- ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
- return clients.get(resourceServer.getId());
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/PermissiveModeAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/PermissiveModeAdapterTest.java
deleted file mode 100644
index c2d7638c75..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/PermissiveModeAdapterTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.authz.example;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Test;
-import org.keycloak.testsuite.arquillian.AppServerTestEnricher;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class PermissiveModeAdapterTest extends AbstractBaseServletAuthzAdapterTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID)
- .addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/servlet-authz-realm.json"), "keycloak-permissive-authz-service.json");
- }
-
- @Test
- public void testCanAccessWhenPermissive() throws Exception {
- performTests(() -> {
- login("jdoe", "jdoe");
- driver.navigate().to(getResourceServerUrl() + "/enforcing/resource");
-
- assertThat(driver.getTitle(), is(equalTo("Error")));
- assertThat(driver.getPageSource(), containsString("Not Found"));
-
- driver.navigate().to(getResourceServerUrl() + "/protected/admin");
- assertWasDenied();
- });
- }
-
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCIPAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCIPAdapterTest.java
deleted file mode 100644
index 87e9511fca..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCIPAdapterTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2018 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.authz.example;
-
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Assert;
-import org.junit.Test;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.util.AdminClientUtil;
-import org.keycloak.testsuite.util.OAuthClient;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletAuthzCIPAdapterTest extends AbstractServletAuthzAdapterTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID)
- .addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/keycloak-claim-information-point-authz-service.json"), "keycloak.json");
- }
-
- @Test
- public void testReuseBodyAfterClaimProcessing() {
- performTests(() -> {
- OAuthClient.AccessTokenResponse response = oauth.realm("servlet-authz").clientId("servlet-authz-app")
- .doGrantAccessTokenRequest("secret", "alice", "alice");
- Client client = AdminClientUtil.createResteasyClient();
- Map body = new HashMap();
-
- body.put("test", "test-value");
-
- Response post = client.target(getResourceServerUrl() + "/protected/filter/body")
- .request()
- .header(HttpHeaders.AUTHORIZATION, "Bearer " + response.getAccessToken())
- .post(Entity.entity(body, MediaType.APPLICATION_JSON_TYPE));
-
- body = post.readEntity(Map.class);
-
- Assert.assertEquals("test-value", body.get("test"));
- });
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCacheDisabledAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCacheDisabledAdapterTest.java
deleted file mode 100644
index 368de74363..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCacheDisabledAdapterTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2018 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.authz.example;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Test;
-import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-
-import java.io.File;
-import java.io.IOException;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletAuthzCacheDisabledAdapterTest extends AbstractServletAuthzAdapterTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID)
- .addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/keycloak-cache-disabled-authz-service.json"), "keycloak.json");
- }
-
- @Test
- public void testCreateNewResource() {
- performTests(() -> {
- login("alice", "alice");
- assertWasNotDenied();
-
- this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
- assertWasNotDenied();
-
- ResourceRepresentation resource = new ResourceRepresentation();
-
- resource.setName("New Resource");
- resource.setUri("/new-resource");
-
- getAuthorizationResource().resources().create(resource);
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName(resource.getName() + " Permission");
- permission.addResource(resource.getName());
- permission.addPolicy("Deny Policy");
-
- permission = getAuthorizationResource().permissions().resource().create(permission).readEntity(ResourcePermissionRepresentation.class);
-
- login("alice", "alice");
- assertWasNotDenied();
-
- this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
- assertWasDenied();
-
- permission = getAuthorizationResource().permissions().resource().findById(permission.getId()).toRepresentation();
-
- permission.removePolicy("Deny Policy");
- permission.addPolicy("Any User Policy");
-
- getAuthorizationResource().permissions().resource().findById(permission.getId()).update(permission);
-
- login("alice", "alice");
- assertWasNotDenied();
-
- this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
- assertWasNotDenied();
- });
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCacheLifespanAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCacheLifespanAdapterTest.java
deleted file mode 100644
index 1fd3988917..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzCacheLifespanAdapterTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2018 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.authz.example;
-
-import java.io.File;
-import java.io.IOException;
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Test;
-import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletAuthzCacheLifespanAdapterTest extends AbstractServletAuthzAdapterTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID)
- .addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/keycloak-cache-lifespan-authz-service.json"), "keycloak.json");
- }
-
- @Test
- public void testCreateNewResourceWaitExpiration() {
- performTests(() -> {
- login("alice", "alice");
- assertWasNotDenied();
-
- this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
- assertWasNotDenied();
-
- ResourceRepresentation resource = new ResourceRepresentation();
-
- resource.setName("New Resource");
- resource.setUri("/new-resource");
-
- getAuthorizationResource().resources().create(resource);
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName(resource.getName() + " Permission");
- permission.addResource(resource.getName());
- permission.addPolicy("Deny Policy");
-
- getAuthorizationResource().permissions().resource().create(permission).readEntity(ResourcePermissionRepresentation.class);
-
- login("alice", "alice");
- assertWasNotDenied();
-
- this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
- assertWasNotDenied();
-
- //Thread.sleep(5000);
- setTimeOffset(30);
- setTimeOffsetOfAdapter(30);
-
- login("alice", "alice");
- assertWasNotDenied();
-
- this.driver.navigate().to(getResourceServerUrl() + "/new-resource");
- assertWasDenied();
-
- resetTimeOffset();
- setTimeOffsetOfAdapter(0);
- });
- }
-
- public void setTimeOffsetOfAdapter(int offset) {
- this.driver.navigate().to(getResourceServerUrl() + "/timeOffset.jsp?offset=" + String.valueOf(offset));
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzLazyLoadPathsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzLazyLoadPathsAdapterTest.java
deleted file mode 100644
index d32b40129c..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzLazyLoadPathsAdapterTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2018 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.authz.example;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletAuthzLazyLoadPathsAdapterTest extends AbstractServletAuthzAdapterTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID)
- .addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/servlet-authz-app/keycloak-lazy-load-authz-service.json"), "keycloak.json");
- }
-
- @Test
- public void testPathPEPDisabled() {
- performTests(() -> {
- login("alice", "alice");
- assertWasNotDenied();
-
- navigateTo();
- getLink("PEP Disabled").click();
-
- hasText("Policy enforcement is disabled. Access granted: true");
- });
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzNoLazyLoadPathsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzNoLazyLoadPathsAdapterTest.java
deleted file mode 100644
index 2f298e2663..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletAuthzNoLazyLoadPathsAdapterTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2018 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.authz.example;
-
-import java.io.IOException;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletAuthzNoLazyLoadPathsAdapterTest extends AbstractServletAuthzAdapterTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() throws IOException {
- return exampleDeployment(RESOURCE_SERVER_ID);
- }
-
-}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletPolicyEnforcerLifespanTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletPolicyEnforcerLifespanTest.java
deleted file mode 100644
index 64da4963ae..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletPolicyEnforcerLifespanTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.authz.example;
-
-import java.io.File;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletPolicyEnforcerLifespanTest extends AbstractServletPolicyEnforcerTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() {
- return exampleDeployment(RESOURCE_SERVER_ID,
- webArchive -> webArchive.addAsWebInfResource(
- new File(TEST_APPS_HOME_DIR
- + "/servlet-policy-enforcer/servlet-policy-enforcer-lifespan-authz-service.json"),
- "keycloak.json"));
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletPolicyEnforcerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletPolicyEnforcerTest.java
deleted file mode 100644
index 1e3eb999dc..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/authz/example/ServletPolicyEnforcerTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.authz.example;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-
-/**
- * @author Pedro Igor
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ServletPolicyEnforcerTest extends AbstractServletPolicyEnforcerTest {
-
- @Deployment(name = RESOURCE_SERVER_ID, managed = false)
- public static WebArchive deployment() {
- return exampleDeployment(RESOURCE_SERVER_ID);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/BrokerLinkAndTokenExchangeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/BrokerLinkAndTokenExchangeTest.java
deleted file mode 100644
index 7313405f3a..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/BrokerLinkAndTokenExchangeTest.java
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
- * 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.servlet;
-
-import com.google.common.collect.ImmutableMap;
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.container.test.api.OperateOnDeployment;
-import org.jboss.arquillian.graphene.page.Page;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.OAuth2Constants;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.authorization.model.Policy;
-import org.keycloak.authorization.model.ResourceServer;
-import org.keycloak.broker.oidc.OIDCIdentityProviderConfig;
-import org.keycloak.broker.oidc.mappers.UserAttributeMapper;
-import org.keycloak.common.Profile;
-import org.keycloak.events.Details;
-import org.keycloak.events.EventType;
-import org.keycloak.exportimport.ExportImportConfig;
-import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
-import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.Constants;
-import org.keycloak.models.IdentityProviderMapperModel;
-import org.keycloak.models.IdentityProviderMapperSyncMode;
-import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.protocol.oidc.OIDCConfigAttributes;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
-import org.keycloak.protocol.oidc.mappers.HardcodedClaim;
-import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.AccessTokenResponse;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.FederatedIdentityRepresentation;
-import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
-import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.representations.idm.ProtocolMapperRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
-import org.keycloak.representations.idm.authorization.DecisionStrategy;
-import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
-import org.keycloak.services.resources.admin.permissions.AdminPermissions;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
-import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
-import org.keycloak.testsuite.arquillian.annotation.UncaughtServerErrorExpected;
-import org.keycloak.testsuite.broker.BrokerTestTools;
-import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
-import org.keycloak.testsuite.pages.ErrorPage;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
-import org.keycloak.testsuite.util.AdminClientUtil;
-import org.keycloak.testsuite.util.OAuthClient;
-import org.keycloak.testsuite.util.WaitUtils;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-import org.keycloak.util.BasicAuthHelper;
-
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.Form;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.UriBuilder;
-import java.io.File;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWithAdminClient;
-
-/**
- *
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-@EnableFeature(value = Profile.Feature.TOKEN_EXCHANGE, skipRestart = true)
-@EnableFeature(value = Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, skipRestart = true)
-public class BrokerLinkAndTokenExchangeTest extends AbstractServletsAdapterTest {
- public static final String CHILD_IDP = "child";
- public static final String PARENT_IDP = "parent-idp";
- public static final String PARENT_USERNAME = "parent";
- public static final String PARENT2_USERNAME = "parent2";
- public static final String PARENT3_USERNAME = "parent3";
- public static final String UNAUTHORIZED_CHILD_CLIENT = "unauthorized-child-client";
- public static final String PARENT_CLIENT = "parent-client";
-
- @Deployment(name = ClientApp.DEPLOYMENT_NAME)
- protected static WebArchive accountLink() {
- return servletDeployment(ClientApp.DEPLOYMENT_NAME, LinkAndExchangeServlet.class, ServletTestUtils.class);
- }
-
- @Page
- protected LoginUpdateProfilePage loginUpdateProfilePage;
-
- @Page
- private LoginPage loginPage;
-
- @Page
- protected ErrorPage errorPage;
-
- public static class ClientApp extends AbstractPageWithInjectedUrl {
-
- public static final String DEPLOYMENT_NAME = "exchange-linking";
-
- @ArquillianResource
- @OperateOnDeployment(DEPLOYMENT_NAME)
- private URL url;
-
- @Override
- public URL getInjectedUrl() {
- return url;
- }
-
- }
-
- @Page
- private ClientApp appPage;
-
- @Rule
- public AssertEvents events = new AssertEvents(this);
-
- @Override
- public void beforeAuthTest() {
- }
-
- @Override
- public void addAdapterTestRealms(List testRealms) {
- RealmRepresentation realm = new RealmRepresentation();
- realm.setRealm(CHILD_IDP);
- realm.setEnabled(true);
- realm.setEventsEnabled(true);
- ClientRepresentation servlet = new ClientRepresentation();
- servlet.setClientId(ClientApp.DEPLOYMENT_NAME);
- servlet.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
- String uri = "/" + ClientApp.DEPLOYMENT_NAME;
- if (!isRelative()) {
- uri = appServerContextRootPage.toString() + uri;
- }
- servlet.setEnabled(true);
- servlet.setAdminUrl(uri);
- servlet.setDirectAccessGrantsEnabled(true);
- servlet.setBaseUrl(uri);
- servlet.setRedirectUris(new LinkedList<>());
- servlet.getRedirectUris().add(uri + "/*");
- servlet.setSecret("password");
- servlet.setFullScopeAllowed(true);
-
- Map attributes = Optional.ofNullable(servlet.getAttributes()).orElse(new HashMap<>());
- attributes.put(OIDCConfigAttributes.EXCLUDE_ISSUER_FROM_AUTH_RESPONSE, Boolean.TRUE.toString());
- servlet.setAttributes(attributes);
-
- realm.setClients(new LinkedList<>());
- realm.getClients().add(servlet);
-
- ClientRepresentation unauthorized = new ClientRepresentation();
- unauthorized.setEnabled(true);
- unauthorized.setClientId(UNAUTHORIZED_CHILD_CLIENT);
- unauthorized.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
- unauthorized.setDirectAccessGrantsEnabled(true);
- unauthorized.setSecret("password");
- unauthorized.setFullScopeAllowed(true);
- realm.getClients().add(unauthorized);
-
- testRealms.add(realm);
-
- realm = new RealmRepresentation();
- realm.setRealm(PARENT_IDP);
- realm.setEnabled(true);
- ClientRepresentation parentApp = new ClientRepresentation();
- parentApp.setEnabled(true);
- parentApp.setClientId(PARENT_CLIENT);
- parentApp.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
- parentApp.setDirectAccessGrantsEnabled(true);
- parentApp.setSecret("password");
- parentApp.setFullScopeAllowed(true);
- realm.setClients(new LinkedList<>());
- realm.getClients().add(parentApp);
- testRealms.add(realm);
-
- }
-
- @Test
- @DisableFeature(value = Profile.Feature.TOKEN_EXCHANGE, skipRestart = true)
- @UncaughtServerErrorExpected
- public void testFeatureDisabled() throws Exception {
- checkFeature(Response.Status.BAD_REQUEST.getStatusCode());
- }
-
- @Test
- public void testFeatureEnabled() throws Exception {
- checkFeature(Response.Status.OK.getStatusCode());
- }
-
- @Before
- public void beforeTest() throws Exception {
- addIdpUser();
- addChildUser();
- createBroker();
- }
-
- public void addIdpUser() {
- RealmResource realm = adminClient.realms().realm(PARENT_IDP);
- UserRepresentation user = new UserRepresentation();
- user.setUsername(PARENT_USERNAME);
- user.setEnabled(true);
- createUserAndResetPasswordWithAdminClient(realm, user, "password");
- user = new UserRepresentation();
- user.setUsername(PARENT2_USERNAME);
- user.setEnabled(true);
- createUserAndResetPasswordWithAdminClient(realm, user, "password");
- user = new UserRepresentation();
- user.setUsername(PARENT3_USERNAME);
- user.setFirstName("first name");
- user.setLastName("last name");
- user.setEmail("email@keycloak.org");
- user.setEnabled(true);
- createUserAndResetPasswordWithAdminClient(realm, user, "password");
- }
-
- private String childUserId = null;
-
- public void addChildUser() {
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- UserRepresentation user = new UserRepresentation();
- user.setUsername("child");
- user.setEnabled(true);
- childUserId = createUserAndResetPasswordWithAdminClient(realm, user, "password");
- UserRepresentation user2 = new UserRepresentation();
- user2.setUsername("child2");
- user2.setEnabled(true);
- String user2Id = createUserAndResetPasswordWithAdminClient(realm, user2, "password");
-
- // have to add a role as undertow default auth manager doesn't like "*". todo we can remove this eventually as undertow fixes this in later versions
- realm.roles().create(new RoleRepresentation("user", null, false));
- RoleRepresentation role = realm.roles().get("user").toRepresentation();
- List roles = new LinkedList<>();
- roles.add(role);
- realm.users().get(childUserId).roles().realmLevel().add(roles);
- realm.users().get(user2Id).roles().realmLevel().add(roles);
- ClientRepresentation brokerService = realm.clients().findByClientId(Constants.BROKER_SERVICE_CLIENT_ID).get(0);
- role = realm.clients().get(brokerService.getId()).roles().get(Constants.READ_TOKEN_ROLE).toRepresentation();
- roles.clear();
- roles.add(role);
- realm.users().get(childUserId).roles().clientLevel(brokerService.getId()).add(roles);
- realm.users().get(user2Id).roles().clientLevel(brokerService.getId()).add(roles);
-
- }
-
- public static void setupRealm(KeycloakSession session) {
- RealmModel realm = session.realms().getRealmByName(CHILD_IDP);
- ClientModel client = realm.getClientByClientId(ClientApp.DEPLOYMENT_NAME);
- IdentityProviderModel idp = realm.getIdentityProviderByAlias(PARENT_IDP);
- Assert.assertNotNull(idp);
-
- ClientModel directExchanger = realm.addClient("direct-exchanger");
- directExchanger.setClientId("direct-exchanger");
- directExchanger.setPublicClient(false);
- directExchanger.setDirectAccessGrantsEnabled(true);
- directExchanger.setEnabled(true);
- directExchanger.setSecret("secret");
- directExchanger.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
- directExchanger.setFullScopeAllowed(false);
-
-
- AdminPermissionManagement management = AdminPermissions.management(session, realm);
- management.idps().setPermissionsEnabled(idp, true);
- ClientPolicyRepresentation clientRep = new ClientPolicyRepresentation();
- clientRep.setName("toIdp");
- clientRep.addClient(client.getId());
- clientRep.addClient(directExchanger.getId());
- ResourceServer server = management.realmResourceServer();
- Policy clientPolicy = management.authz().getStoreFactory().getPolicyStore().create(server, clientRep);
- management.idps().exchangeToPermission(idp).addAssociatedPolicy(clientPolicy);
-
-
- // permission for user impersonation for a client
-
- ClientPolicyRepresentation clientImpersonateRep = new ClientPolicyRepresentation();
- clientImpersonateRep.setName("clientImpersonators");
- clientImpersonateRep.addClient(directExchanger.getId());
- server = management.realmResourceServer();
- Policy clientImpersonatePolicy = management.authz().getStoreFactory().getPolicyStore().create(server, clientImpersonateRep);
- management.users().setPermissionsEnabled(true);
- management.users().adminImpersonatingPermission().addAssociatedPolicy(clientImpersonatePolicy);
- management.users().adminImpersonatingPermission().setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
-
- }
- public static void turnOffTokenStore(KeycloakSession session) {
- RealmModel realm = session.realms().getRealmByName(CHILD_IDP);
- IdentityProviderModel idp = realm.getIdentityProviderByAlias(PARENT_IDP);
- idp.setStoreToken(false);
- realm.updateIdentityProvider(idp);
-
- }
- public static void turnOnTokenStore(KeycloakSession session) {
- RealmModel realm = session.realms().getRealmByName(CHILD_IDP);
- IdentityProviderModel idp = realm.getIdentityProviderByAlias(PARENT_IDP);
- idp.setStoreToken(true);
- realm.updateIdentityProvider(idp);
- }
-
- public void createBroker() {
- createParentChild();
- testingClient.server().run(BrokerLinkAndTokenExchangeTest::setupRealm);
- }
-
- public void createParentChild() {
- BrokerTestTools.createKcOidcBroker(adminClient, CHILD_IDP, PARENT_IDP);
- }
-
-
- @Test
- @UncaughtServerErrorExpected
- public void testAccountLink() throws Exception {
- testingClient.server().run(BrokerLinkAndTokenExchangeTest::turnOnTokenStore);
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- String servletUri = appPage.getInjectedUrl().toString();
- UriBuilder linkBuilder = UriBuilder.fromUri(servletUri)
- .path("link");
- String linkUrl = linkBuilder.clone()
- .queryParam("realm", CHILD_IDP)
- .queryParam("provider", PARENT_IDP).build().toString();
- System.out.println("linkUrl: " + linkUrl);
- navigateTo(linkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- Assert.assertTrue(driver.getPageSource().contains(PARENT_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue(loginPage.isCurrent(PARENT_IDP));
- loginPage.login(PARENT_USERNAME, "password");
- System.out.println("After linking: " + driver.getCurrentUrl());
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getCurrentUrl().startsWith(linkBuilder.toTemplate()));
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
- Assert.assertTrue(driver.getPageSource().contains("Exchange token received"));
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertFalse(links.isEmpty());
-
-
- // do exchange
-
- String accessToken = oauth.doGrantAccessTokenRequest(CHILD_IDP, "child", "password", null, ClientApp.DEPLOYMENT_NAME, "password").getAccessToken();
- Client httpClient = AdminClientUtil.createResteasyClient();
- try {
- WebTarget exchangeUrl = childTokenExchangeWebTarget(httpClient);
- System.out.println("Exchange url: " + exchangeUrl.getUri().toString());
-
- Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE)
- .param(OAuth2Constants.REQUESTED_ISSUER, PARENT_IDP)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- response.close();
- String externalToken = tokenResponse.getToken();
- Assert.assertNotNull(externalToken);
- Assert.assertTrue(tokenResponse.getExpiresIn() > 0);
- setTimeOffset((int) tokenResponse.getExpiresIn() + 1);
-
- // test that token refresh happens
-
- // get access token again because we may have timed out
- accessToken = oauth.doGrantAccessTokenRequest(CHILD_IDP, "child", "password", null, ClientApp.DEPLOYMENT_NAME, "password").getAccessToken();
- response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE)
- .param(OAuth2Constants.REQUESTED_ISSUER, PARENT_IDP)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- tokenResponse = response.readEntity(AccessTokenResponse.class);
- response.close();
- Assert.assertNotEquals(externalToken, tokenResponse.getToken());
-
- // test direct exchange
- response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader("direct-exchanger", "secret"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.REQUESTED_SUBJECT, "child")
- .param(OAuth2Constants.REQUESTED_ISSUER, PARENT_IDP)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- tokenResponse = response.readEntity(AccessTokenResponse.class);
- response.close();
- Assert.assertNotEquals(externalToken, tokenResponse.getToken());
-
-
- resetTimeOffset();
- logoutAll();
-
-
- realm.users().get(childUserId).removeFederatedIdentity(PARENT_IDP);
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
- } finally {
- httpClient.close();
- }
- }
-
- protected WebTarget childTokenExchangeWebTarget(Client httpClient) {
- return httpClient.target(OAuthClient.AUTH_SERVER_ROOT)
- .path("/realms")
- .path(CHILD_IDP)
- .path("protocol/openid-connect/token");
-
- }
- protected WebTarget childLogoutWebTarget(Client httpClient) {
- return httpClient.target(OAuthClient.AUTH_SERVER_ROOT)
- .path("/realms")
- .path(CHILD_IDP)
- .path("protocol/openid-connect/logout");
-
- }
- protected String parentJwksUrl() {
- return UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)
- .path("/realms")
- .path(PARENT_IDP)
- .path("protocol/openid-connect")
- .path(OIDCLoginProtocolService.class, "certs").build().toString();
-
- }
-
- @Test
- @UncaughtServerErrorExpected
- public void testAccountLinkNoTokenStore() {
- testingClient.server().run(BrokerLinkAndTokenExchangeTest::turnOffTokenStore);
-
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- UriBuilder linkBuilder = UriBuilder.fromUri(appPage.getInjectedUrl().toString())
- .path("link");
- String linkUrl = linkBuilder.clone()
- .queryParam("realm", CHILD_IDP)
- .queryParam("provider", PARENT_IDP).build().toString();
- System.out.println("linkUrl: " + linkUrl);
- navigateTo(linkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- Assert.assertTrue(driver.getPageSource().contains(PARENT_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue("Unexpected page. Current Page URL: " + driver.getCurrentUrl(),loginPage.isCurrent(PARENT_IDP));
- loginPage.login(PARENT_USERNAME, "password");
- System.out.println("After linking: " + driver.getCurrentUrl());
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getCurrentUrl().startsWith(linkBuilder.toTemplate()));
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
- Assert.assertTrue(driver.getPageSource().contains("Exchange token received"));
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertFalse(links.isEmpty());
-
-
- logoutAll();
-
-
- realm.users().get(childUserId).removeFederatedIdentity(PARENT_IDP);
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
- }
-
-
- /**
- * KEYCLOAK-6026
- */
- @Test
- @UncaughtServerErrorExpected
- public void testExportImport() throws Exception {
- testExternalExchange();
-
- try {
- testingClient.testing().exportImport().setProvider(SingleFileExportProviderFactory.PROVIDER_ID);
- String targetFilePath = testingClient.testing().exportImport().getExportImportTestDirectory() + File.separator + "singleFile-full.json";
- testingClient.testing().exportImport().setFile(targetFilePath);
- testingClient.testing().exportImport().setAction(ExportImportConfig.ACTION_EXPORT);
- testingClient.testing().exportImport().setRealmName(CHILD_IDP);
- testingClient.testing().exportImport().runExport();
-
- adminClient.realms().realm(CHILD_IDP).remove();
- testingClient.testing().exportImport().setAction(ExportImportConfig.ACTION_IMPORT);
-
- testingClient.testing().exportImport().runImport();
- } finally {
- testingClient.testing().exportImport().clear();
- }
-
- testExternalExchange();
- }
-
- @Test
- @UncaughtServerErrorExpected
- public void testExternalExchange() throws Exception {
- RealmResource childRealm = adminClient.realms().realm(CHILD_IDP);
-
- String accessToken = oauth.doGrantAccessTokenRequest(PARENT_IDP, PARENT2_USERNAME, "password", null, PARENT_CLIENT, "password").getAccessToken();
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
- Client httpClient = AdminClientUtil.createResteasyClient();
- try {
- WebTarget exchangeUrl = childTokenExchangeWebTarget(httpClient);
- System.out.println("Exchange url: " + exchangeUrl.getUri().toString());
-
- checkFeature(200);
-
- IdentityProviderRepresentation rep = adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).toRepresentation();
- rep.getConfig().put(OIDCIdentityProviderConfig.VALIDATE_SIGNATURE, String.valueOf(true));
- rep.getConfig().put(OIDCIdentityProviderConfig.USE_JWKS_URL, String.valueOf(true));
- rep.getConfig().put(OIDCIdentityProviderConfig.JWKS_URL, parentJwksUrl());
- String parentIssuer = UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)
- .path("/realms")
- .path(PARENT_IDP)
- .build().toString();
- rep.getConfig().put("issuer", parentIssuer);
- adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).update(rep);
-
- String exchangedUserId;
- String exchangedUsername;
-
- {
- // test signature validation
- Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SUBJECT_ISSUER, PARENT_IDP)
- .param(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- String idToken = tokenResponse.getIdToken();
- JWSInput jws = new JWSInput(tokenResponse.getToken());
- AccessToken token = jws.readJsonContent(AccessToken.class);
- response.close();
-
- exchangedUserId = token.getSubject();
- exchangedUsername = token.getPreferredUsername();
-
- System.out.println("exchangedUserId: " + exchangedUserId);
- System.out.println("exchangedUsername: " + exchangedUsername);
-
-
- // test that we can exchange back to external token
- response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, tokenResponse.getToken())
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE)
- .param(OAuth2Constants.REQUESTED_ISSUER, PARENT_IDP)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- tokenResponse = response.readEntity(AccessTokenResponse.class);
- Assert.assertEquals(accessToken, tokenResponse.getToken());
- response.close();
-
- Assert.assertEquals(1, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
- // test logout
- response = childLogoutWebTarget(httpClient)
- .queryParam("id_token_hint", idToken)
- .request()
- .get();
- response.close();
-
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
-
- List links = childRealm.users().get(exchangedUserId).getFederatedIdentity();
- Assert.assertEquals(1, links.size());
- }
- {
- // check that we can request an exchange again and that the previously linked user is obtained
- Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SUBJECT_ISSUER, PARENT_IDP)
- .param(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- String idToken = tokenResponse.getIdToken();
- JWSInput jws = new JWSInput(tokenResponse.getToken());
- AccessToken token = jws.readJsonContent(AccessToken.class);
- response.close();
-
- String exchanged2UserId = token.getSubject();
- String exchanged2Username = token.getPreferredUsername();
-
- // assert that we get the same linked account as was previously imported
-
- Assert.assertEquals(exchangedUserId, exchanged2UserId);
- Assert.assertEquals(exchangedUsername, exchanged2Username);
-
- // test logout
- response = childLogoutWebTarget(httpClient)
- .queryParam("id_token_hint", idToken)
- .request()
- .get();
- response.close();
-
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
-
- List links = childRealm.users().get(exchangedUserId).getFederatedIdentity();
- Assert.assertEquals(1, links.size());
- }
- {
- // check that we can exchange without specifying an SUBJECT_ISSUER
- Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
-
- ));
- Assert.assertEquals(200, response.getStatus());
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- String idToken = tokenResponse.getIdToken();
- JWSInput jws = new JWSInput(tokenResponse.getToken());
- AccessToken token = jws.readJsonContent(AccessToken.class);
- response.close();
-
- String exchanged2UserId = token.getSubject();
- String exchanged2Username = token.getPreferredUsername();
-
- // assert that we get the same linked account as was previously imported
-
- Assert.assertEquals(exchangedUserId, exchanged2UserId);
- Assert.assertEquals(exchangedUsername, exchanged2Username);
-
- // test logout
- response = childLogoutWebTarget(httpClient)
- .queryParam("id_token_hint", idToken)
- .request()
- .get();
- response.close();
-
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
-
- List links = childRealm.users().get(exchangedUserId).getFederatedIdentity();
- Assert.assertEquals(1, links.size());
- }
- // cleanup remove the user
- childRealm.users().get(exchangedUserId).remove();
-
- {
- // test unauthorized client gets 403
- try (Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(UNAUTHORIZED_CHILD_CLIENT, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SUBJECT_ISSUER, PARENT_IDP)
-
- ))) {
- Assert.assertEquals(403, response.getStatus());
- }
- }
- } finally {
- httpClient.close();
- }
- }
-
- /**
- * KEYCLOAK-14577, see also KEYCLOAK-10932
- */
- @Test
- public void testExternalExchange_extractIdentityFromProfile() throws Exception {
- RealmResource childRealm = adminClient.realms().realm(CHILD_IDP);
-
- String accessToken = oauth.doGrantAccessTokenRequest(PARENT_IDP, PARENT3_USERNAME, "password", null, PARENT_CLIENT, "password").getAccessToken();
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
- Client httpClient = AdminClientUtil.createResteasyClient();
- try {
- WebTarget exchangeUrl = childTokenExchangeWebTarget(httpClient);
- IdentityProviderRepresentation rep = adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).toRepresentation();
- rep.getConfig().put(OIDCIdentityProviderConfig.VALIDATE_SIGNATURE, String.valueOf(false));
- adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).update(rep);
-
- AccessToken token;
- try (Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SUBJECT_ISSUER, PARENT_IDP)
- .param(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
- ))) {
- Assert.assertEquals(200, response.getStatus());
-
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- JWSInput jws = new JWSInput(tokenResponse.getToken());
- token = jws.readJsonContent(AccessToken.class);
- }
-
- Assert.assertNotNull(token);
- Assert.assertNotNull(token.getSubject());
- Assert.assertEquals(PARENT3_USERNAME, token.getPreferredUsername());
- Assert.assertEquals("first name", token.getGivenName());
- Assert.assertEquals("last name", token.getFamilyName());
- Assert.assertEquals("email@keycloak.org", token.getEmail());
-
- // cleanup remove the user
- childRealm.users().get(token.getSubject()).remove();
- } finally {
- httpClient.close();
- }
- }
-
- @Test
- public void testExternalExchangeCreateNewUserUsingMappers() throws Exception {
- RealmResource parentRealm = adminClient.realms().realm(PARENT_IDP);
- ProtocolMapperRepresentation claimMapper = new ProtocolMapperRepresentation();
- claimMapper.setName("custom-claim-hardcoded-mapper");
- claimMapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
- claimMapper.setProtocolMapper(HardcodedClaim.PROVIDER_ID);
- Map config = new HashMap<>();
- config.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "claim-from-idp");
- config.put(HardcodedClaim.CLAIM_VALUE, "true");
- config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
- config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true");
- claimMapper.setConfig(config);
- ClientRepresentation client = parentRealm.clients().findByClientId(PARENT_CLIENT).get(0);
- ClientResource clientResource = parentRealm.clients().get(client.getId());
- clientResource.getProtocolMappers().createMapper(claimMapper).close();
-
- RealmResource childRealm = adminClient.realms().realm(CHILD_IDP);
- IdentityProviderMapperRepresentation attributeMapper = new IdentityProviderMapperRepresentation();
- attributeMapper.setName("attribute-mapper");
- attributeMapper.setIdentityProviderMapper(UserAttributeMapper.PROVIDER_ID);
- attributeMapper.setIdentityProviderAlias(PARENT_IDP);
- attributeMapper.setConfig(ImmutableMap.builder()
- .put(IdentityProviderMapperModel.SYNC_MODE, IdentityProviderMapperSyncMode.INHERIT.toString())
- .put(UserAttributeMapper.CLAIM, "claim-from-idp")
- .put(UserAttributeMapper.USER_ATTRIBUTE, "claim-to-broker")
- .build());
- childRealm.identityProviders().get(PARENT_IDP).addMapper(attributeMapper).close();
-
- String idToken = oauth.doGrantAccessTokenRequest(PARENT_IDP, PARENT3_USERNAME, "password", null, PARENT_CLIENT, "password").getAccessToken();
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
- try (Client httpClient = AdminClientUtil.createResteasyClient()) {
- WebTarget exchangeUrl = childTokenExchangeWebTarget(httpClient);
- IdentityProviderRepresentation rep = adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).toRepresentation();
- rep.getConfig().put(OIDCIdentityProviderConfig.VALIDATE_SIGNATURE, String.valueOf(false));
- adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).update(rep);
-
- AccessToken token;
- try (Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, idToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SUBJECT_ISSUER, PARENT_IDP)
- .param(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
- ))) {
- Assert.assertEquals(200, response.getStatus());
-
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- JWSInput jws = new JWSInput(tokenResponse.getToken());
- token = jws.readJsonContent(AccessToken.class);
- }
-
- UserRepresentation newUser = childRealm.users().search(PARENT3_USERNAME).get(0);
- Assert.assertNotNull(newUser.getAttributes());
- Assert.assertTrue(newUser.getAttributes().containsKey("claim-to-broker"));
- events.expect(EventType.REGISTER)
- .realm(childRealm.toRepresentation())
- .client("exchange-linking")
- .user(newUser)
- .detail(Details.IDENTITY_PROVIDER, PARENT_IDP)
- .assertEvent(childRealm.getEvents().get(1));
-
- // cleanup remove the user
- childRealm.users().get(token.getSubject()).remove();
- }
- }
-
- public void logoutAll() {
- adminClient.realm(CHILD_IDP).logoutAll();
- adminClient.realm(PARENT_IDP).logoutAll();
- }
-
- private void navigateTo(String uri) {
- driver.navigate().to(uri);
- WaitUtils.waitForPageToLoad();
- }
-
- private void checkFeature(int statusCode) throws Exception {
- String accessToken = oauth.doGrantAccessTokenRequest(PARENT_IDP, PARENT2_USERNAME, "password", null, PARENT_CLIENT, "password").getAccessToken();
-
- if (statusCode != Response.Status.BAD_REQUEST.getStatusCode()) {
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
- }
-
- Client httpClient = AdminClientUtil.createResteasyClient();
- try {
- WebTarget exchangeUrl = childTokenExchangeWebTarget(httpClient);
- {
- IdentityProviderRepresentation rep = adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).toRepresentation();
- rep.getConfig().put(OIDCIdentityProviderConfig.VALIDATE_SIGNATURE, String.valueOf(false));
- adminClient.realm(CHILD_IDP).identityProviders().get(PARENT_IDP).update(rep);
- // test user info validation.
- Response response = exchangeUrl.request()
- .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(ClientApp.DEPLOYMENT_NAME, "password"))
- .post(Entity.form(
- new Form()
- .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE)
- .param(OAuth2Constants.SUBJECT_TOKEN, accessToken)
- .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.JWT_TOKEN_TYPE)
- .param(OAuth2Constants.SUBJECT_ISSUER, PARENT_IDP)
- .param(OAuth2Constants.SCOPE, OAuth2Constants.SCOPE_OPENID)
-
- ));
- Assert.assertEquals(statusCode, response.getStatus());
-
- if (statusCode != Response.Status.BAD_REQUEST.getStatusCode()) {
- AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class);
- String idToken = tokenResponse.getIdToken();
- Assert.assertNotNull(idToken);
- response.close();
-
- Assert.assertEquals(1, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
-
- // test logout
- response = childLogoutWebTarget(httpClient)
- .queryParam("id_token_hint", idToken)
- .request()
- .get();
- response.close();
-
- Assert.assertEquals(0, adminClient.realm(CHILD_IDP).getClientSessionStats().size());
- }
- }
- } finally {
- httpClient.close();
- }
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java
deleted file mode 100644
index 39d206d05c..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * 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.servlet;
-
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.container.test.api.OperateOnDeployment;
-import org.jboss.arquillian.graphene.page.Page;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.IdentityProviderResource;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.broker.provider.HardcodedAttributeMapper;
-import org.keycloak.common.Profile;
-import org.keycloak.common.util.Base64Url;
-import org.keycloak.models.Constants;
-import org.keycloak.models.IdentityProviderMapperModel;
-import org.keycloak.models.IdentityProviderMapperSyncMode;
-import org.keycloak.protocol.oidc.OIDCConfigAttributes;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.representations.AccessTokenResponse;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.FederatedIdentityRepresentation;
-import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
-import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.services.resources.LoginActionsService;
-import org.keycloak.testsuite.ActionURIUtils;
-import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-import org.keycloak.testsuite.broker.BrokerTestTools;
-import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
-import org.keycloak.testsuite.pages.ErrorPage;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
-import org.keycloak.testsuite.util.AdminClientUtil;
-import org.keycloak.testsuite.util.OAuthClient;
-import org.keycloak.testsuite.util.WaitUtils;
-import org.keycloak.util.JsonSerialization;
-
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.core.UriBuilder;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT;
-import static org.keycloak.models.AccountRoles.MANAGE_ACCOUNT_LINKS;
-import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
-import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWithAdminClient;
-import static org.keycloak.testsuite.util.ServerURLs.getAuthServerContextRoot;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class ClientInitiatedAccountLinkTest extends AbstractServletsAdapterTest {
- public static final String CHILD_IDP = "child";
- public static final String PARENT_IDP = "parent-idp";
- public static final String PARENT_USERNAME = "parent";
- private static final String HARDCODED_ATTRIBUTE_MAPPER_NAME = "my_hardcoded_mapper";
- private static final String USER_ATTRIBUTE = "hardcoded_attribute";
- private static final String USER_ATTRIBUTE_VALUE = "hardcoded_value";
-
- @Page
- protected LoginUpdateProfilePage loginUpdateProfilePage;
-
- @Page
- private LoginPage loginPage;
-
- @Page
- protected ErrorPage errorPage;
-
- public static class ClientApp extends AbstractPageWithInjectedUrl {
-
- public static final String DEPLOYMENT_NAME = "client-linking";
-
- @ArquillianResource
- @OperateOnDeployment(DEPLOYMENT_NAME)
- private URL url;
-
- @Override
- public URL getInjectedUrl() {
- return url;
- }
-
- }
-
- @Page
- private ClientApp appPage;
-
- @Override
- public void beforeAuthTest() {
- }
-
- @Override
- public void addAdapterTestRealms(List testRealms) {
- RealmRepresentation realm = new RealmRepresentation();
- realm.setRealm(CHILD_IDP);
- realm.setEnabled(true);
- ClientRepresentation servlet = new ClientRepresentation();
- servlet.setClientId("client-linking");
- servlet.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
- String uri = "/client-linking";
- servlet.setAdminUrl(uri);
- servlet.setDirectAccessGrantsEnabled(true);
- servlet.setBaseUrl(uri);
- servlet.setRedirectUris(new LinkedList<>());
- servlet.getRedirectUris().add(uri + "/*");
- servlet.setSecret("password");
- servlet.setFullScopeAllowed(true);
-
- Map attributes = Optional.ofNullable(servlet.getAttributes()).orElse(new HashMap<>());
- attributes.put(OIDCConfigAttributes.EXCLUDE_ISSUER_FROM_AUTH_RESPONSE, Boolean.TRUE.toString());
- servlet.setAttributes(attributes);
-
- realm.setClients(new LinkedList<>());
- realm.getClients().add(servlet);
- testRealms.add(realm);
-
-
- realm = new RealmRepresentation();
- realm.setRealm(PARENT_IDP);
- realm.setEnabled(true);
-
- testRealms.add(realm);
-
- }
-
- @Deployment(name = ClientApp.DEPLOYMENT_NAME)
- protected static WebArchive accountLink() {
- return servletDeployment(ClientApp.DEPLOYMENT_NAME, ClientInitiatedAccountLinkServlet.class, ServletTestUtils.class);
- }
-
- @Before
- public void addIdpUser() {
- RealmResource realm = adminClient.realms().realm(PARENT_IDP);
- UserRepresentation user = new UserRepresentation();
- user.setUsername(PARENT_USERNAME);
- user.setEnabled(true);
- String userId = createUserAndResetPasswordWithAdminClient(realm, user, "password");
-
- }
-
- private String childUserId = null;
-
- @Before
- public void addChildUser() {
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- UserRepresentation user = new UserRepresentation();
- user.setUsername("child");
- user.setEnabled(true);
- childUserId = createUserAndResetPasswordWithAdminClient(realm, user, "password");
- UserRepresentation user2 = new UserRepresentation();
- user2.setUsername("child2");
- user2.setEnabled(true);
- String user2Id = createUserAndResetPasswordWithAdminClient(realm, user2, "password");
-
- // have to add a role as undertow default auth manager doesn't like "*". todo we can remove this eventually as undertow fixes this in later versions
- realm.roles().create(new RoleRepresentation("user", null, false));
- RoleRepresentation role = realm.roles().get("user").toRepresentation();
- List roles = new LinkedList<>();
- roles.add(role);
- realm.users().get(childUserId).roles().realmLevel().add(roles);
- realm.users().get(user2Id).roles().realmLevel().add(roles);
- ClientRepresentation brokerService = realm.clients().findByClientId(Constants.BROKER_SERVICE_CLIENT_ID).get(0);
- role = realm.clients().get(brokerService.getId()).roles().get(Constants.READ_TOKEN_ROLE).toRepresentation();
- roles.clear();
- roles.add(role);
- realm.users().get(childUserId).roles().clientLevel(brokerService.getId()).add(roles);
- realm.users().get(user2Id).roles().clientLevel(brokerService.getId()).add(roles);
-
- }
-
- @Before
- public void createBroker() {
- createParentChild();
- }
-
- public void createParentChild() {
- BrokerTestTools.createKcOidcBroker(adminClient, CHILD_IDP, PARENT_IDP);
- }
-
-
- @Test
- public void testErrorConditions() throws Exception {
- String helloUrl = appPage.getUriBuilder().clone().path("hello").build().toASCIIString();
-
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- ClientRepresentation client = adminClient.realms().realm(CHILD_IDP).clients().findByClientId("client-linking").get(0);
-
- UriBuilder redirectUri = UriBuilder.fromUri(appPage.getInjectedUrl().toString())
- .path("link")
- .queryParam("response", "true");
-
- UriBuilder directLinking = UriBuilder.fromUri(getAuthServerContextRoot() + "/auth")
- .path("realms/child/broker/{provider}/link")
- .queryParam("client_id", "client-linking")
- .queryParam("redirect_uri", redirectUri.build())
- .queryParam("hash", Base64Url.encode("crap".getBytes()))
- .queryParam("nonce", UUID.randomUUID().toString());
-
- String linkUrl = directLinking
- .build(PARENT_IDP).toString();
-
- // test not logged in
-
- navigateTo(linkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
-
- Assert.assertTrue(driver.getCurrentUrl().contains("link_error=not_logged_in"));
-
- logoutAll();
-
- // now log in
-
-
- navigateTo(helloUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue(driver.getCurrentUrl().startsWith(helloUrl));
- Assert.assertTrue(driver.getPageSource().contains("Unknown request:"));
-
- // now test CSRF with bad hash.
-
- navigateTo(linkUrl);
-
- Assert.assertTrue(driver.getPageSource().contains("We are sorry..."));
-
- logoutAll();
-
- // now log in again with client that does not have scope
-
- String accountId = adminClient.realms().realm(CHILD_IDP).clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0).getId();
- RoleRepresentation manageAccount = adminClient.realms().realm(CHILD_IDP).clients().get(accountId).roles().get(MANAGE_ACCOUNT).toRepresentation();
- RoleRepresentation manageLinks = adminClient.realms().realm(CHILD_IDP).clients().get(accountId).roles().get(MANAGE_ACCOUNT_LINKS).toRepresentation();
- RoleRepresentation userRole = adminClient.realms().realm(CHILD_IDP).roles().get("user").toRepresentation();
-
- client.setFullScopeAllowed(false);
- ClientResource clientResource = adminClient.realms().realm(CHILD_IDP).clients().get(client.getId());
- clientResource.update(client);
-
- List roles = new LinkedList<>();
- roles.add(userRole);
- clientResource.getScopeMappings().realmLevel().add(roles);
-
- navigateTo(helloUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue(driver.getCurrentUrl().startsWith(helloUrl));
- Assert.assertTrue(driver.getPageSource().contains("Unknown request:"));
-
-
- UriBuilder linkBuilder = UriBuilder.fromUri(appPage.getInjectedUrl().toString())
- .path("link");
- String clientLinkUrl = linkBuilder.clone()
- .queryParam("realm", CHILD_IDP)
- .queryParam("provider", PARENT_IDP).build().toString();
-
-
- navigateTo(clientLinkUrl);
-
- Assert.assertTrue(driver.getCurrentUrl().contains("error=not_allowed"));
-
- logoutAll();
-
- // add MANAGE_ACCOUNT_LINKS scope should pass.
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
-
- roles = new LinkedList<>();
- roles.add(manageLinks);
- clientResource.getScopeMappings().clientLevel(accountId).add(roles);
-
- navigateTo(clientLinkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue(loginPage.isCurrent(PARENT_IDP));
- loginPage.login(PARENT_USERNAME, "password");
-
- Assert.assertTrue(driver.getCurrentUrl().startsWith(linkBuilder.toTemplate()));
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertFalse(links.isEmpty());
-
- realm.users().get(childUserId).removeFederatedIdentity(PARENT_IDP);
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- clientResource.getScopeMappings().clientLevel(accountId).remove(roles);
-
- logoutAll();
-
- navigateTo(clientLinkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
-
- Assert.assertTrue(driver.getCurrentUrl().contains("link_error=not_allowed"));
-
- logoutAll();
-
- // add MANAGE_ACCOUNT scope should pass
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
-
- roles = new LinkedList<>();
- roles.add(manageAccount);
- clientResource.getScopeMappings().clientLevel(accountId).add(roles);
-
- navigateTo(clientLinkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue(loginPage.isCurrent(PARENT_IDP));
- loginPage.login(PARENT_USERNAME, "password");
-
- Assert.assertTrue(driver.getCurrentUrl().startsWith(linkBuilder.toTemplate()));
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertFalse(links.isEmpty());
-
- realm.users().get(childUserId).removeFederatedIdentity(PARENT_IDP);
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- clientResource.getScopeMappings().clientLevel(accountId).remove(roles);
-
- logoutAll();
-
- navigateTo(clientLinkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
-
- Assert.assertTrue(driver.getCurrentUrl().contains("link_error=not_allowed"));
-
- logoutAll();
-
-
- // undo fullScopeAllowed
-
- client = adminClient.realms().realm(CHILD_IDP).clients().findByClientId("client-linking").get(0);
- client.setFullScopeAllowed(true);
- clientResource.update(client);
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- logoutAll();
- }
-
- // TODO remove this once DYNAMIC_SCOPES feature is enabled by default
- @Test
- @EnableFeature(value = Profile.Feature.DYNAMIC_SCOPES, skipRestart = true)
- public void testErrorConditionsWithDynamicScope() throws Exception {
- // Just use existing test with DYNAMIC_SCOPES feature enabled as it was failing with DYNAMIC_SCOPES
- testErrorConditions();
- }
-
- @Test
- public void testAccountLink() throws Exception {
- linkAccount();
-
- OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest(CHILD_IDP, "child", "password", null, "client-linking", "password");
- Assert.assertNotNull(response.getAccessToken());
- Assert.assertNull(response.getError());
- Client httpClient = AdminClientUtil.createResteasyClient();
- String firstToken = getToken(response, httpClient);
- Assert.assertNotNull(firstToken);
-
- navigateToAccountLinkPage();
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
- String nextToken = getToken(response, httpClient);
- Assert.assertNotNull(nextToken);
- Assert.assertNotEquals(firstToken, nextToken);
-
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertFalse(links.isEmpty());
-
- realm.users().get(childUserId).removeFederatedIdentity(PARENT_IDP);
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- logoutAll();
- }
-
- // TODO remove this once DYNAMIC_SCOPES feature is enabled by default
- @Test
- @EnableFeature(value = Profile.Feature.DYNAMIC_SCOPES, skipRestart = true)
- public void testAccountLinkWithDynamicScope() throws Exception {
- // Just use existing test with DYNAMIC_SCOPES feature enabled as it was failing with DYNAMIC_SCOPES
- testAccountLink();
- }
-
- private String getToken(OAuthClient.AccessTokenResponse response, Client httpClient) throws Exception {
- String idpToken = httpClient.target(OAuthClient.AUTH_SERVER_ROOT)
- .path("realms")
- .path("child/broker")
- .path(PARENT_IDP)
- .path("token")
- .request()
- .header("Authorization", "Bearer " + response.getAccessToken())
- .get(String.class);
- AccessTokenResponse res = JsonSerialization.readValue(idpToken, AccessTokenResponse.class);
- return res.getToken();
- }
-
- public void logoutAll() {
- adminClient.realm(CHILD_IDP).logoutAll();
- adminClient.realm(PARENT_IDP).logoutAll();
- }
-
- @Test
- public void testLinkOnlyProvider() throws Exception {
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- IdentityProviderRepresentation rep = realm.identityProviders().get(PARENT_IDP).toRepresentation();
- rep.setLinkOnly(true);
- realm.identityProviders().get(PARENT_IDP).update(rep);
- try {
-
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- UriBuilder linkBuilder = UriBuilder.fromUri(appPage.getInjectedUrl().toString())
- .path("link");
- String linkUrl = linkBuilder.clone()
- .queryParam("realm", CHILD_IDP)
- .queryParam("provider", PARENT_IDP).build().toString();
- navigateTo(linkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
-
- // should not be on login page. This is what we are testing
- Assert.assertFalse(driver.getPageSource().contains(PARENT_IDP));
-
- // now test that we can still link.
- loginPage.login("child", "password");
- Assert.assertTrue(loginPage.isCurrent(PARENT_IDP));
- loginPage.login(PARENT_USERNAME, "password");
- System.out.println("After linking: " + driver.getCurrentUrl());
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getCurrentUrl().startsWith(linkBuilder.toTemplate()));
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
-
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertFalse(links.isEmpty());
-
- realm.users().get(childUserId).removeFederatedIdentity(PARENT_IDP);
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- logoutAll();
-
- System.out.println("testing link-only attack");
-
- navigateTo(linkUrl);
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
-
- System.out.println("login page uri is: " + driver.getCurrentUrl());
-
- // ok, now scrape the code from page
- String pageSource = driver.getPageSource();
- String action = ActionURIUtils.getActionURIFromPageSource(pageSource);
- System.out.println("action uri: " + action);
-
- Map queryParams = ActionURIUtils.parseQueryParamsFromActionURI(action);
- System.out.println("query params: " + queryParams);
-
- // now try and use the code to login to remote link-only idp
-
- String uri = "/auth/realms/child/broker/parent-idp/login";
-
- uri = UriBuilder.fromUri(getAuthServerContextRoot())
- .path(uri)
- .queryParam(LoginActionsService.SESSION_CODE, queryParams.get(LoginActionsService.SESSION_CODE))
- .queryParam(Constants.CLIENT_ID, queryParams.get(Constants.CLIENT_ID))
- .queryParam(Constants.TAB_ID, queryParams.get(Constants.TAB_ID))
- .build().toString();
-
- System.out.println("hack uri: " + uri);
-
- navigateTo(uri);
-
- Assert.assertTrue(driver.getPageSource().contains("Could not send authentication request to identity provider."));
-
-
-
-
-
- } finally {
-
- rep.setLinkOnly(false);
- realm.identityProviders().get(PARENT_IDP).update(rep);
- }
-
-
- }
-
- @Test
- public void testAccountLinkingExpired() {
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- // Login to application first
- appPage.navigateTo();
- WaitUtils.waitForPageToLoad();
-
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- loginPage.login("child", "password");
-
- // Now in another tab, request account linking
- UriBuilder linkBuilder = UriBuilder.fromUri(appPage.getInjectedUrl().toString())
- .path("link");
- String linkUrl = linkBuilder.clone()
- .queryParam("realm", CHILD_IDP)
- .queryParam("provider", PARENT_IDP).build().toString();
- navigateTo(linkUrl);
-
- Assert.assertTrue(loginPage.isCurrent(PARENT_IDP));
-
- // Logout "child" userSession in the meantime (for example through admin request)
- realm.logoutAll();
-
- // Finish login on parent.
- loginPage.login(PARENT_USERNAME, "password");
-
- // Test I was not automatically linked
- links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- errorPage.assertCurrent();
- Assert.assertEquals("Requested broker account linking, but current session is no longer valid.", errorPage.getError());
-
- logoutAll();
- }
-
- private void navigateTo(String uri) {
- driver.navigate().to(uri);
- WaitUtils.waitForPageToLoad();
- }
-
- @Test
- public void testAccountLinkWithHardcodedMapper() throws Exception {
- driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.DAYS);
- addHardcodedAttributeMapper();
- linkAccount();
- assertHardcodedAttributeHasBeenAssigned();
- removeHardcodedAttribute();
- removeHardcodedAttributeMapper();
- logoutAll();
- }
-
- private void addHardcodedAttributeMapper() {
- IdentityProviderResource provider = adminClient.realms().realm(CHILD_IDP).identityProviders().get(PARENT_IDP);
-
- IdentityProviderMapperRepresentation mapper = new IdentityProviderMapperRepresentation();
- mapper.setIdentityProviderAlias(PARENT_IDP);
- mapper.setName(HARDCODED_ATTRIBUTE_MAPPER_NAME);
- mapper.setIdentityProviderMapper("hardcoded-attribute-idp-mapper");
- mapper.setConfig(Map.of(
- IdentityProviderMapperModel.SYNC_MODE, IdentityProviderMapperSyncMode.FORCE.toString(),
- HardcodedAttributeMapper.ATTRIBUTE, USER_ATTRIBUTE,
- HardcodedAttributeMapper.ATTRIBUTE_VALUE, USER_ATTRIBUTE_VALUE)
- );
-
- mapper.setIdentityProviderAlias(PARENT_IDP);
- provider.addMapper(mapper).close();
- }
-
- private void removeHardcodedAttributeMapper() {
- IdentityProviderResource provider = adminClient.realms().realm(CHILD_IDP).identityProviders().get(PARENT_IDP);
- Optional mapper = provider.getMappers().stream()
- .filter(m -> m.getName().equals(HARDCODED_ATTRIBUTE_MAPPER_NAME)).findFirst();
-
- Assert.assertFalse(mapper.isEmpty());
-
- provider.delete(mapper.get().getId());
- }
-
- private void assertHardcodedAttributeHasBeenAssigned() {
- UserRepresentation user = adminClient.realm(CHILD_IDP).users().get(childUserId).toRepresentation();
- Assert.assertEquals(USER_ATTRIBUTE_VALUE, user.firstAttribute(USER_ATTRIBUTE));
- }
-
- private void removeHardcodedAttribute() {
- UserRepresentation user = adminClient.realm(CHILD_IDP).users().get(childUserId).toRepresentation();
- user.getAttributes().remove(USER_ATTRIBUTE);
- adminClient.realm(CHILD_IDP).users().get(user.getId()).update(user);
- }
-
- private void linkAccount() {
- RealmResource realm = adminClient.realms().realm(CHILD_IDP);
- List links = realm.users().get(childUserId).getFederatedIdentity();
- Assert.assertTrue(links.isEmpty());
-
- navigateToAccountLinkPage();
- Assert.assertTrue(loginPage.isCurrent(CHILD_IDP));
- Assert.assertTrue(driver.getPageSource().contains(PARENT_IDP));
- loginPage.login("child", "password");
- Assert.assertTrue(loginPage.isCurrent(PARENT_IDP));
- loginPage.login(PARENT_USERNAME, "password");
- System.out.println("After linking: " + driver.getCurrentUrl());
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("Account Linked"));
- }
-
- private void navigateToAccountLinkPage() {
- UriBuilder linkBuilder = UriBuilder.fromUri(appPage.getInjectedUrl().toString())
- .path("link");
- String linkUrl = linkBuilder.clone()
- .queryParam("realm", CHILD_IDP)
- .queryParam("provider", PARENT_IDP).build().toString();
- System.out.println("linkUrl: " + linkUrl);
- navigateTo(linkUrl);
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/DemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/DemoServletsAdapterTest.java
deleted file mode 100644
index 1dc3e2850a..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/DemoServletsAdapterTest.java
+++ /dev/null
@@ -1,1475 +0,0 @@
-/*
- * 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.servlet;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.impl.client.BasicCookieStore;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.cookie.BasicClientCookie;
-import org.apache.http.util.EntityUtils;
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.graphene.page.Page;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Before;
-import org.junit.After;
-import org.junit.Test;
-import org.keycloak.OAuth2Constants;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.common.util.Time;
-import org.keycloak.constants.AdapterConstants;
-import org.keycloak.events.Details;
-import org.keycloak.models.utils.SessionTimeoutHelper;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.AccessTokenResponse;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
-import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
-import org.keycloak.testsuite.adapter.page.BasicAuth;
-import org.keycloak.testsuite.adapter.page.ClientSecretJwtSecurePortal;
-import org.keycloak.testsuite.adapter.page.ClientSecretJwtSecurePortalValidAlg;
-import org.keycloak.testsuite.adapter.page.CustomerCookiePortal;
-import org.keycloak.testsuite.adapter.page.CustomerCookiePortalRoot;
-import org.keycloak.testsuite.adapter.page.CustomerDb;
-import org.keycloak.testsuite.adapter.page.CustomerDbAudienceRequired;
-import org.keycloak.testsuite.adapter.page.CustomerDbErrorPage;
-import org.keycloak.testsuite.adapter.page.CustomerPortal;
-import org.keycloak.testsuite.adapter.page.CustomerPortalNoConf;
-import org.keycloak.testsuite.adapter.page.InputPortal;
-import org.keycloak.testsuite.adapter.page.InputPortalNoAccessToken;
-import org.keycloak.testsuite.adapter.page.ProductPortal;
-import org.keycloak.testsuite.adapter.page.ProductPortalAutodetectBearerOnly;
-import org.keycloak.testsuite.adapter.page.SecurePortal;
-import org.keycloak.testsuite.adapter.page.SecurePortalRewriteRedirectUri;
-import org.keycloak.testsuite.adapter.page.SecurePortalWithCustomSessionConfig;
-import org.keycloak.testsuite.adapter.page.TokenMinTTLPage;
-import org.keycloak.testsuite.adapter.page.TokenRefreshPage;
-import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
-import org.keycloak.testsuite.pages.InfoPage;
-import org.keycloak.testsuite.pages.LogoutConfirmPage;
-import org.keycloak.testsuite.util.ServerURLs;
-import org.keycloak.testsuite.utils.arquillian.ContainerConstants;
-import org.keycloak.testsuite.auth.page.login.OAuthGrant;
-import org.keycloak.testsuite.console.page.events.Config;
-import org.keycloak.testsuite.console.page.events.LoginEvents;
-import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
-import org.keycloak.testsuite.util.Matchers;
-import org.keycloak.testsuite.util.URLUtils;
-import org.keycloak.testsuite.util.WaitUtils;
-import org.keycloak.testsuite.util.AccountHelper;
-import org.keycloak.util.BasicAuthHelper;
-import org.openqa.selenium.By;
-import org.openqa.selenium.Cookie;
-
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.Form;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.Status;
-import jakarta.ws.rs.core.UriBuilder;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
-import static org.keycloak.testsuite.util.AdminClientUtil.NUMBER_OF_CONNECTIONS;
-import static org.keycloak.testsuite.util.AdminClientUtil.createResteasyClient;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
-import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
-
-/**
- *
- * @author tkyjovsk
- */
-@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW)
-public class DemoServletsAdapterTest extends AbstractServletsAdapterTest {
-
- @Page
- protected LogoutConfirmPage logoutConfirmPage;
-
- @Page
- protected InfoPage infoPage;
-
- @Page
- protected CustomerPortal customerPortal;
- @Page
- private CustomerPortalNoConf customerPortalNoConf;
- @Page
- private SecurePortal securePortal;
- @Page
- private SecurePortalWithCustomSessionConfig securePortalWithCustomSessionConfig;
- @Page
- private SecurePortalRewriteRedirectUri securePortalRewriteRedirectUri;
- @Page
- private CustomerDb customerDb;
- @Page
- private CustomerDbErrorPage customerDbErrorPage;
- @Page
- private ProductPortal productPortal;
- @Page
- private ProductPortalAutodetectBearerOnly productPortalAutodetectBearerOnly;
- @Page
- private InputPortal inputPortal;
- @Page
- private InputPortalNoAccessToken inputPortalNoAccessToken;
- @Page
- private TokenMinTTLPage tokenMinTTLPage;
- @Page
- private TokenRefreshPage tokenRefreshPage;
- @Page
- private OAuthGrant oAuthGrantPage;
- @Page
- protected LoginEvents loginEventsPage;
- @Page
- private BasicAuth basicAuthPage;
- @Page
- protected Config configPage;
- @Page
- private ClientSecretJwtSecurePortal clientSecretJwtSecurePortal;
- @Page
- private ClientSecretJwtSecurePortalValidAlg clientSecretJwtSecurePortalValidAlg;
- @Page
- private CustomerCookiePortal customerCookiePortal;
- @Page
- private CustomerCookiePortalRoot customerCookiePortalRoot;
-
- @Rule
- public AssertEvents assertEvents = new AssertEvents(this);
-
- @Deployment(name = CustomerPortal.DEPLOYMENT_NAME)
- protected static WebArchive customerPortal() {
- return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
- }
-
- @Deployment(name = CustomerCookiePortal.DEPLOYMENT_NAME)
- protected static WebArchive customerCookiePortal() {
- return servletDeployment(CustomerCookiePortal.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
- }
-
- @Deployment(name = CustomerPortalNoConf.DEPLOYMENT_NAME)
- protected static WebArchive customerPortalNoConf() {
- return servletDeployment(CustomerPortalNoConf.DEPLOYMENT_NAME, CustomerServletNoConf.class, ErrorServlet.class, ServletTestUtils.class);
- }
-
- @Deployment(name = SecurePortal.DEPLOYMENT_NAME)
- protected static WebArchive securePortal() {
- return servletDeployment(SecurePortal.DEPLOYMENT_NAME, AdapterActionsFilter.class, CallAuthenticatedServlet.class);
- }
- @Deployment(name = SecurePortalRewriteRedirectUri.DEPLOYMENT_NAME)
- protected static WebArchive securePortalRewriteRedirectUri() {
- return servletDeployment(SecurePortalRewriteRedirectUri.DEPLOYMENT_NAME, CallAuthenticatedServlet.class);
- }
-
-
- @Deployment(name = SecurePortalWithCustomSessionConfig.DEPLOYMENT_NAME)
- protected static WebArchive securePortalWithCustomSessionConfig() {
- return servletDeployment(SecurePortalWithCustomSessionConfig.DEPLOYMENT_NAME, CallAuthenticatedServlet.class);
- }
-
- @Deployment(name = CustomerDb.DEPLOYMENT_NAME)
- protected static WebArchive customerDb() {
- return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class);
- }
-
- @Deployment(name = CustomerDbAudienceRequired.DEPLOYMENT_NAME)
- protected static WebArchive customerDbAudienceRequired() {
- return servletDeployment(CustomerDbAudienceRequired.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class);
- }
-
- @Deployment(name = CustomerDbErrorPage.DEPLOYMENT_NAME)
- protected static WebArchive customerDbErrorPage() {
- return servletDeployment(CustomerDbErrorPage.DEPLOYMENT_NAME, CustomerDatabaseServlet.class, ErrorServlet.class);
- }
-
- @Deployment(name = ProductPortal.DEPLOYMENT_NAME)
- protected static WebArchive productPortal() {
- return servletDeployment(ProductPortal.DEPLOYMENT_NAME, ProductServlet.class);
- }
-
- @Deployment(name = ProductPortalAutodetectBearerOnly.DEPLOYMENT_NAME)
- protected static WebArchive productPortalAutodetectBearerOnly() {
- return servletDeployment(ProductPortalAutodetectBearerOnly.DEPLOYMENT_NAME, ProductServlet.class);
- }
-
- @Deployment(name = InputPortal.DEPLOYMENT_NAME)
- protected static WebArchive inputPortal() {
- return servletDeployment(InputPortal.DEPLOYMENT_NAME, "keycloak.json", InputServlet.class, ServletTestUtils.class);
- }
-
- @Deployment(name = InputPortalNoAccessToken.DEPLOYMENT_NAME)
- protected static WebArchive inputPortalNoAccessToken() {
- return servletDeployment(InputPortalNoAccessToken.DEPLOYMENT_NAME, "keycloak.json", InputServlet.class, ServletTestUtils.class);
- }
-
- @Deployment(name = TokenMinTTLPage.DEPLOYMENT_NAME)
- protected static WebArchive tokenMinTTLPage() {
- return servletDeployment(TokenMinTTLPage.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, TokenMinTTLServlet.class, ErrorServlet.class);
- }
-
- @Deployment(name = TokenRefreshPage.DEPLOYMENT_NAME)
- protected static WebArchive tokenRefresh() {
- return servletDeployment(TokenRefreshPage.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, TokenMinTTLServlet.class, ErrorServlet.class);
- }
-
- @Deployment(name = BasicAuth.DEPLOYMENT_NAME)
- protected static WebArchive basicAuth() {
- return servletDeployment(BasicAuth.DEPLOYMENT_NAME, BasicAuthServlet.class);
- }
-
- @Deployment(name = ClientSecretJwtSecurePortal.DEPLOYMENT_NAME)
- protected static WebArchive clientSecretSecurePortal() {
- return servletDeployment(ClientSecretJwtSecurePortal.DEPLOYMENT_NAME, CallAuthenticatedServlet.class);
- }
-
- @Deployment(name = ClientSecretJwtSecurePortalValidAlg.DEPLOYMENT_NAME)
- protected static WebArchive clientSecretSecurePortalValidAlg() {
- return servletDeployment(ClientSecretJwtSecurePortalValidAlg.DEPLOYMENT_NAME, CallAuthenticatedServlet.class);
- }
-
- @Deployment(name = CustomerCookiePortalRoot.DEPLOYMENT_NAME)
- protected static WebArchive customerCookiePortalRoot() {
- return servletDeployment(CustomerCookiePortalRoot.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
- }
-
- @Override
- public void setDefaultPageUriParameters() {
- super.setDefaultPageUriParameters();
- configPage.setConsoleRealm(DEMO);
- loginEventsPage.setConsoleRealm(DEMO);
- loginEventsPage.setConsoleRealm(DEMO);
- oAuthGrantPage.setAuthRealm(DEMO);
- }
-
- @Before
- public void beforeDemoServletsAdapterTest() {
- // Delete all cookies from token-min-ttl page to be sure we are logged out
- tokenMinTTLPage.navigateTo();
- driver.manage().deleteAllCookies();
-
- // set demo realm name for all tests
- oauth.realm(testRealmResource().toRepresentation().getRealm());
- createAppClientInRealm(testRealmResource().toRepresentation().getRealm());
- }
-
- @After
- public void afterDemoServletsAdapterTest() {
- // restore test realm
- oauth.realm("test");
- }
-
- //KEYCLOAK-702
- @Test
- public void testTokenInCookieSSO() {
- // Login
- String tokenCookie = loginToCustomerCookiePortal();
-
- // SSO to second app
- customerPortal.navigateTo();
- assertLogged();
-
- // return to customer-cookie-portal and assert still same cookie (accessToken didn't expire)
- customerCookiePortal.navigateTo();
- assertLogged();
- String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
- assertEquals(tokenCookie, tokenCookie2);
-
- // Logout with httpServletRequest
- logoutFromCustomerCookiePortal();
-
- // Also should be logged-out from the second app
- customerPortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- }
-
- //KEYCLOAK-702
- @Test
- public void testTokenInCookieRefresh() {
- log.debug("Set token timeout 10 sec");
- RealmRepresentation demo = adminClient.realm("demo").toRepresentation();
- int originalTokenTimeout = demo.getAccessTokenLifespan();
- demo.setAccessTokenLifespan(10);
- adminClient.realm("demo").update(demo);
-
- try {
- log.debug("login to customer-cookie-portal");
- String tokenCookie1 = loginToCustomerCookiePortal();
-
- log.debug("Simulate waiting 12 seconds");
- setAdapterAndServerTimeOffset(12, customerCookiePortal.toString());
-
- log.debug("assert cookie was refreshed");
- customerCookiePortal.navigateTo();
- assertCurrentUrlEquals(customerCookiePortal);
- assertLogged();
- String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
- assertNotEquals(tokenCookie1, tokenCookie2);
-
- log.debug("login to 2nd app and logout from it");
- customerPortal.navigateTo();
- assertCurrentUrlEquals(customerPortal);
- assertLogged();
-
- driver.navigate().to(customerPortal.logout().toASCIIString());
- WaitUtils.waitUntilElement(By.id("customer_portal_logout")).is().present();
- customerPortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
-
- log.debug("Simulate another 12 seconds");
- setAdapterAndServerTimeOffset(24, customerCookiePortal.toString());
-
- log.debug("assert not logged in customer-cookie-portal");
- customerCookiePortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- } finally {
- log.debug("Set token timeout to original");
- demo.setAccessTokenLifespan(originalTokenTimeout);
- adminClient.realm("demo").update(demo);
-
- log.debug("reset time offset");
- setAdapterAndServerTimeOffset(0, customerCookiePortal.toString().concat("/unsecured"));
- }
- }
-
- //KEYCLOAK-702
- @Test
- public void testInvalidTokenCookie() {
- // Login
- String tokenCookie = loginToCustomerCookiePortal();
- String changedTokenCookie = tokenCookie.replace("a", "b");
-
- // change cookie to invalid value
- driver.manage().addCookie(new Cookie(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE, changedTokenCookie, "/customer-cookie-portal"));
-
- // visit page and assert re-logged and cookie was refreshed
- customerCookiePortal.navigateTo();
- assertCurrentUrlEquals(customerCookiePortal);
- String currentCookie = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
- assertNotEquals(currentCookie, tokenCookie);
- assertNotEquals(currentCookie, changedTokenCookie);
-
- // logout
- logoutFromCustomerCookiePortal();
- }
-
- // login to customer-cookie-portal and return the KEYCLOAK_ADAPTER_STATE cookie established on adapter
- private String loginToCustomerCookiePortal() {
- customerCookiePortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- testRealmLoginPage.form().login("bburke@redhat.com", "password");
- assertCurrentUrlEquals(customerCookiePortal);
- assertLogged();
-
- // Assert no JSESSIONID cookie
- Assert.assertNull(driver.manage().getCookieNamed("JSESSIONID"));
-
- return driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
- }
-
- private void logoutFromCustomerCookiePortal() {
- String logout = customerCookiePortal.logoutURL();
- driver.navigate().to(logout);
- WaitUtils.waitUntilElement(By.id("customer_portal_logout")).is().present();
- assertNull(driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE));
- customerCookiePortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- }
-
- protected void assertLogged() {
- assertPageContains("Bill Burke");
- assertPageContains("Stian Thorgersen");
- }
-
- private void assertPageContains(String string) {
- String pageSource = driver.getPageSource();
- assertThat(pageSource, containsString(string));
- }
-
- @Test
- public void testSavedPostRequest() throws Exception {
- // test login to customer-portal which does a bearer request to customer-db
- inputPortal.navigateTo();
- assertCurrentUrlEquals(inputPortal);
- inputPortal.execute("hello");
-
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- testRealmLoginPage.form().login("bburke@redhat.com", "password");
- assertCurrentUrlEquals(inputPortal.getUriBuilder().clone().path("secured").path("post").build());
- waitForPageToLoad();
- assertPageContains("parameter=hello");
-
- AccountHelper.logout(testRealmResource(), "bburke@redhat.com");
- driver.navigate().to(oauth.getLoginFormUrl());
-
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- productPortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- customerPortal.navigateTo();
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
-
- // test unsecured POST KEYCLOAK-901
- Client client = createResteasyClient(true, false);
- try {
- Form form = new Form();
- form.param("parameter", "hello");
- String text = client.target(inputPortal + "/unsecured").request().post(Entity.form(form), String.class);
- assertThat(text, containsString("parameter=hello"));
- } finally {
- client.close();
- }
- }
-
- @Test
- public void testLoginSSOAndLogout() {
- // test login to customer-portal which does a bearer request to customer-db
- customerPortal.navigateTo();
- assertTrue(testRealmLoginPage.form().isUsernamePresent());
- assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
- testRealmLoginPage.form().login("bburke@redhat.com", "password");
- assertCurrentUrlEquals(customerPortal);
- assertLogged();
-
- // test SSO
- productPortal.navigateTo();
- assertCurrentUrlEquals(productPortal);
- assertPageContains("iPhone");
- assertPageContains("iPad");
-
- // View stats
- List