diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml index f110d28cc9..94122ce543 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml @@ -377,59 +377,6 @@ - - - adapter-install-offline-standalone - process-resources - - exec - - - ${skip.adapter.offline.installation} - ${cli.executable} - ${cli.working.dir} - - ${app.server.java.home} - - - ${cli.jboss-cli.arg} - --file=${app.server.jboss.home}/bin/adapter-install-offline.cli - - ${cli.win.working.dir} - - - - - - adapter-install-offline-standalone-ha - process-resources - - exec - - - ${skip.adapter.offline.installation} - ${cli.executable} - ${cli.working.dir} - - ${app.server.java.home} - - - ${cli.jboss-cli.arg} - --file=${app.server.jboss.home}/bin/adapter-install-offline.cli - - ${cli.win.working.dir} - -Dserver.config=standalone-ha.xml - - - adapter-install-saml-offline-standalone diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/README.md b/testsuite/integration-arquillian/test-apps/app-profile-jee/README.md deleted file mode 100644 index 71bb42fbdd..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/README.md +++ /dev/null @@ -1,10 +0,0 @@ -You need to create a client in Keycloak. The configuration options when creating the client should be: - -* Client ID: You choose -* Access Type: confidential -* Root URL: Root URL for where you're hosting the application (for example http://localhost:8080) -* Valie Redirect URIs: /app-profile-jee/* -* Base URL: /app-profile-jee/ -* Admin URL: /app-profile-jee/ - -Then, build the WAR with Maven and install as per the Adapter configuration for your server as described in the Keycloak documentation. \ No newline at end of file diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml b/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml deleted file mode 100644 index 1bd6c5a6ed..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - 4.0.0 - - - org.keycloak.testsuite - integration-arquillian-test-apps - 999.0.0-SNAPSHOT - - - keycloak-test-app-profile-jee - - Keycloak Test App Profile JEE - - - war - - - - - - - org.jboss.spec.javax.servlet - jboss-servlet-api_4.0_spec - provided - - - org.keycloak - keycloak-core - provided - - - org.keycloak.testsuite - integration-arquillian-util - ${project.version} - - - org.keycloak - keycloak-adapter-spi - provided - - - - - app-profile-jee - - - org.wildfly.plugins - wildfly-maven-plugin - - false - - - - - diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/java/org/keycloak/quickstart/profilejee/Controller.java b/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/java/org/keycloak/quickstart/profilejee/Controller.java deleted file mode 100644 index 2f863b913d..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/java/org/keycloak/quickstart/profilejee/Controller.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * - * 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.quickstart.profilejee; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.common.util.KeycloakUriBuilder; -import org.keycloak.constants.ServiceUrlConstants; -import org.keycloak.representations.IDToken; -import org.keycloak.util.JsonSerialization; - -/** - * Controller simplifies access to the server environment from the JSP. - * - * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc. - */ -public class Controller { - - public void handleLogout(HttpServletRequest req) throws ServletException { - if (req.getParameter("logout") != null) { - req.logout(); - } - } - - public boolean isLoggedIn(HttpServletRequest req) { - return getSession(req) != null; - } - - public boolean showToken(HttpServletRequest req) { - return req.getParameter("showToken") != null; - } - - public IDToken getIDToken(HttpServletRequest req) { - return getSession(req).getIdToken(); - } - - public String getAccountUri(HttpServletRequest req) { - KeycloakSecurityContext session = getSession(req); - String baseUrl = getAuthServerBaseUrl(req); - String realm = session.getRealm(); - return KeycloakUriBuilder.fromUri(baseUrl).path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH) - .queryParam("referrer", "app-profile-jee").build(realm).toString(); - - } - - private String getAuthServerBaseUrl(HttpServletRequest req) { - AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext) req.getServletContext().getAttribute(AdapterDeploymentContext.class.getName()); - KeycloakDeployment deployment = deploymentContext.resolveDeployment(null); - return deployment.getAuthServerBaseUrl(); - } - - public String getTokenString(HttpServletRequest req) throws IOException { - return JsonSerialization.writeValueAsPrettyString(getIDToken(req)); - } - - private KeycloakSecurityContext getSession(HttpServletRequest req) { - return (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName()); - } -} diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/WEB-INF/keycloak.json b/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/WEB-INF/keycloak.json deleted file mode 100644 index 4094da4b8d..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/WEB-INF/keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm": "Test", - "auth-server-url": "/auth", - "ssl-required": "external", - "resource": "app-profile-jee", - "credentials": { - "secret": "4f36f31a-be9d-4f92-b982-425301bac5df" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/WEB-INF/web.xml b/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 397e8d044a..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - app-profile-jee - - - - Protected - /profile.jsp - - - user - - - - - KEYCLOAK - - - - user - - - diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/index.jsp b/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/index.jsp deleted file mode 100644 index beab97258c..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/index.jsp +++ /dev/null @@ -1,47 +0,0 @@ -<%-- - * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * - * 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. ---%> - -<%@page contentType="text/html" pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> - - - - - Keycloak Example App - - - - - - <% controller.handleLogout(request); %> - - - - - - -
- - -
-
Please login
-
-
- - diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/profile.jsp b/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/profile.jsp deleted file mode 100644 index 0b74a945bc..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/profile.jsp +++ /dev/null @@ -1,79 +0,0 @@ -<%-- - * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * - * 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. ---%> - -<%@page contentType="text/html" pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> - - - - - Keycloak Example App - - - - - - - - - -
- - - -
-
${tokenString}
- -
-
- - -
-
- - - - - - - - - - - - - - - - - -
First name${idToken.givenName}
Last name${idToken.familyName}
Username${idToken.preferredUsername}
Email${idToken.email}
-
-
-
-
- - diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/styles.css b/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/styles.css deleted file mode 100644 index 815abe4b8c..0000000000 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/src/main/webapp/styles.css +++ /dev/null @@ -1,101 +0,0 @@ - -body { - background-color: #333; - font-family: sans-serif; - font-size: 30px; -} - -button { - font-family: sans-serif; - font-size: 30px; - width: 200px; - - background-color: #0085cf; - background-image: linear-gradient(to bottom, #00a8e1 0%, #0085cf 100%); - background-repeat: repeat-x; - - border: 2px solid #ccc; - color: #fff; - -webkit-border-radius: 30px; - - text-transform: uppercase; - - -webkit-box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.5); - -moz-box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.5); - box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.5); -} - -button:hover { - background-color: #006ba6; - background-image: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -hr { - border: none; - background-color: #eee; - height: 10px; -} - -.menu { - padding: 10px; - margin-bottom: 10px; -} - -.content { - background-color: #eee; - border: 1px solid #ccc; - padding: 10px; - -webkit-border-radius: 10px; - - -webkit-box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.5); - -moz-box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.5); - box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.5); -} - -.content .message { - padding: 10px; - background-color: #fff; - border: 1px solid #ccc; - font-size: 40px; - -webkit-border-radius: 10px; -} - -#token .content .message { - font-size: 20px; - overflow: scroll; - padding: 5px; - white-space: pre; - text-transform: none; -} - -.wrapper { - position: absolute; - left: 10px; - top: 10px; - bottom: 10px; - right: 10px; -} - -.error { - color: #a21e22; -} - -table { - width: 100%; -} - -tr.even { - background-color: #eee; -} - -td { - padding: 5px; -} - -td.label { - font-weight: bold; - width: 250px; -} diff --git a/testsuite/integration-arquillian/test-apps/pom.xml b/testsuite/integration-arquillian/test-apps/pom.xml index 2729e6662c..f9a001475e 100644 --- a/testsuite/integration-arquillian/test-apps/pom.xml +++ b/testsuite/integration-arquillian/test-apps/pom.xml @@ -21,7 +21,6 @@ servlet-policy-enforcer servlets servlets-jakarta - app-profile-jee cors diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java index 3b3cc4997f..9e97fc9b8f 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java @@ -19,18 +19,13 @@ package org.keycloak.testsuite.adapter.filter; import org.jboss.logging.Logger; -import org.keycloak.adapters.AdapterDeploymentContext; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.rotation.JWKPublicKeyLocator; import org.keycloak.common.util.Time; -import org.keycloak.common.util.reflections.Reflections; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; -import java.lang.reflect.Field; /** * Filter to handle "special" requests to perform actions on adapter side (for example setting time offset ) @@ -40,7 +35,6 @@ import java.lang.reflect.Field; public class AdapterActionsFilter implements Filter { public static final String TIME_OFFSET_PARAM = "timeOffset"; - public static final String RESET_DEPLOYMENT_PARAM = "resetDeployment"; private static final Logger log = Logger.getLogger(AdapterActionsFilter.class); @@ -56,28 +50,12 @@ public class AdapterActionsFilter implements Filter { //Accept timeOffset as argument to enforce timeouts String timeOffsetParam = request.getParameter(TIME_OFFSET_PARAM); - String resetDeploymentParam = request.getParameter(RESET_DEPLOYMENT_PARAM); if (timeOffsetParam != null && !timeOffsetParam.isEmpty()) { int timeOffset = Integer.parseInt(timeOffsetParam); log.infof("Time offset updated to %d for application %s", timeOffset, servletReq.getRequestURI()); Time.setOffset(timeOffset); writeResponse(servletResp, "Offset set successfully"); - } else if (resetDeploymentParam != null && !resetDeploymentParam.isEmpty()) { - AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext) request.getServletContext().getAttribute(AdapterDeploymentContext.class.getName()); - - Field field = Reflections.findDeclaredField(AdapterDeploymentContext.class, "deployment"); - Reflections.setAccessible(field); - KeycloakDeployment deployment = (KeycloakDeployment) Reflections.getFieldValue(field, deploymentContext); - - Time.setOffset(0); - deployment.setNotBefore(0); - if (deployment.getPublicKeyLocator() instanceof JWKPublicKeyLocator) { - deployment.setPublicKeyLocator(new JWKPublicKeyLocator()); - } - - log.infof("Restarted PublicKeyLocator, notBefore and timeOffset for application %s", servletReq.getRequestURI()); - writeResponse(servletResp, "Restarted PublicKeyLocator, notBefore and timeOffset successfully"); } else { // Continue request chain.doFilter(request, response); diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java deleted file mode 100644 index b4daf27e41..0000000000 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java +++ /dev/null @@ -1,58 +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.KeycloakSecurityContext; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; -import org.keycloak.jose.jws.JWSInput; -import org.keycloak.jose.jws.JWSInputException; -import org.keycloak.representations.RefreshToken; -import org.keycloak.util.JsonSerialization; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; - -/** - * @author Marek Posolda - */ -public abstract class AbstractShowTokensServlet extends HttpServlet { - - private static final String LINK = "%s"; - - protected String renderTokens(HttpServletRequest req) throws ServletException, IOException { - RefreshableKeycloakSecurityContext ctx = (RefreshableKeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName()); - String accessTokenPretty = JsonSerialization.writeValueAsPrettyString(ctx.getToken()); - RefreshToken refreshToken; - try { - refreshToken = new JWSInput(ctx.getRefreshToken()).readJsonContent(RefreshToken.class); - } catch (JWSInputException e) { - throw new IOException(e); - } - String refreshTokenPretty = JsonSerialization.writeValueAsPrettyString(refreshToken); - - return new StringBuilder("" + accessTokenPretty + "") - .append("" + refreshTokenPretty + "") - .append("" + ctx.getTokenString() + "") - .append("" + ctx.getRefreshToken() + "") - .toString(); - } - - -} diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/LinkAndExchangeServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/LinkAndExchangeServlet.java deleted file mode 100644 index 00a17e64cb..0000000000 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/LinkAndExchangeServlet.java +++ /dev/null @@ -1,193 +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.http.HttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.util.EntityUtils; -import org.junit.Assert; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.OAuth2Constants; -import org.keycloak.adapters.HttpClientBuilder; -import org.keycloak.common.util.KeycloakUriBuilder; -import org.keycloak.representations.AccessToken; -import org.keycloak.representations.AccessTokenResponse; -import org.keycloak.util.BasicAuthHelper; -import org.keycloak.util.JsonSerialization; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@WebServlet("/exchange-linking") -public class LinkAndExchangeServlet extends HttpServlet { - - private String getPostDataString(HashMap params) throws UnsupportedEncodingException{ - StringBuilder result = new StringBuilder(); - boolean first = true; - for(Map.Entry entry : params.entrySet()){ - if (first) - first = false; - else - result.append("&"); - - result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); - result.append("="); - result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); - } - - return result.toString(); - } - - public AccessTokenResponse doTokenExchange(String realm, String token, String requestedIssuer, - String clientId, String clientSecret) throws Exception { - - try (CloseableHttpClient client = (CloseableHttpClient) new HttpClientBuilder().disableTrustManager().build()) { - String exchangeUrl = KeycloakUriBuilder.fromUri(ServletTestUtils.getAuthServerUrlBase()) - .path("/auth/realms/{realm}/protocol/openid-connect/token").build(realm).toString(); - - HttpPost post = new HttpPost(exchangeUrl); - HashMap parameters = new HashMap<>(); - - if (clientSecret != null) { - String authorization = BasicAuthHelper.createHeader(clientId, clientSecret); - post.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); - post.setHeader(HttpHeaders.AUTHORIZATION, authorization); - } else { - parameters.put("client_id", clientId); - } - - parameters.put(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE); - parameters.put(OAuth2Constants.SUBJECT_TOKEN, token); - parameters.put(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE); - parameters.put(OAuth2Constants.REQUESTED_ISSUER, requestedIssuer); - - post.setEntity(new StringEntity(getPostDataString(parameters))); - HttpResponse response = client.execute(post); - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode == 200 || statusCode == 400) { - return JsonSerialization.readValue(EntityUtils.toString(response.getEntity()), AccessTokenResponse.class); - } else { - throw new RuntimeException("Unknown error!"); - } - } - } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { - resp.setHeader("Cache-Control", "no-cache"); - if (request.getRequestURI().endsWith("/link") && request.getParameter("response") == null) { - String provider = request.getParameter("provider"); - String realm = request.getParameter("realm"); - KeycloakSecurityContext session = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); - AccessToken token = session.getToken(); - String tokenString = session.getTokenString(); - - String clientId = token.getIssuedFor(); - String linkUrl = null; - try { - AccessTokenResponse response = doTokenExchange(realm, tokenString, provider, clientId, "password"); - String error = response.getError(); - if (error != null) { - System.out.println("*** error : " + error); - System.out.println("*** link-url: " + response.getOtherClaims().get("account-link-url")); - linkUrl = (String)response.getOtherClaims().get("account-link-url"); - } else { - Assert.assertNotNull(response.getToken()); - resp.setStatus(200); - resp.setContentType("text/html"); - PrintWriter pw = resp.getWriter(); - pw.printf("%s", "Client Linking"); - pw.println("Account Linked"); - pw.print(""); - pw.flush(); - return; - } - } catch (Exception e) { - throw new RuntimeException(e); - } - - String redirectUri = KeycloakUriBuilder.fromUri(request.getRequestURL().toString()) - .replaceQuery(null) - .queryParam("response", "true") - .queryParam("realm", realm) - .queryParam("provider", provider).build().toString(); - String accountLinkUrl = KeycloakUriBuilder.fromUri(linkUrl) - .queryParam("redirect_uri", redirectUri).build().toString(); - resp.setStatus(302); - resp.setHeader("Location", accountLinkUrl); - } else if (request.getRequestURI().endsWith("/link") && request.getParameter("response") != null) { - resp.setStatus(200); - resp.setContentType("text/html"); - PrintWriter pw = resp.getWriter(); - pw.printf("%s", "Client Linking"); - String error = request.getParameter("link_error"); - if (error != null) { - pw.println("Link error: " + error); - } else { - pw.println("Account Linked"); - } - pw.println("trying exchange"); - try { - String provider = request.getParameter("provider"); - String realm = request.getParameter("realm"); - KeycloakSecurityContext session = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); - AccessToken token = session.getToken(); - String clientId = token.getIssuedFor(); - String tokenString = session.getTokenString(); - AccessTokenResponse response = doTokenExchange(realm, tokenString, provider, clientId, "password"); - error = (String)response.getOtherClaims().get("error"); - if (error == null) { - if (response.getToken() != null) pw.println("Exchange token received"); - } else { - pw.print("Error with exchange: " + error); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - pw.print(""); - pw.flush(); - } else { - resp.setStatus(200); - resp.setContentType("text/html"); - PrintWriter pw = resp.getWriter(); - pw.printf("%s", "Client Linking"); - pw.println("Unknown request: " + request.getRequestURL().toString()); - pw.print(""); - pw.flush(); - - } - - } -} diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/MultiTenantResolver.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/MultiTenantResolver.java deleted file mode 100644 index 9bd7873f1e..0000000000 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/MultiTenantResolver.java +++ /dev/null @@ -1,56 +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.adapters.KeycloakConfigResolver; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; -import org.keycloak.adapters.spi.HttpFacade; - -import java.io.InputStream; - -/** - * - * @author Juraci Paixão Kröhling - */ -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> stats = testRealmResource().getClientSessionStats(); - Map customerPortalStats = null; - Map productPortalStats = null; - for (Map s : stats) { - switch (s.get("clientId")) { - case "customer-portal": - customerPortalStats = s; - break; - case "product-portal": - productPortalStats = s; - break; - } - } - assertEquals(1, Integer.parseInt(customerPortalStats.get("active"))); - assertEquals(1, Integer.parseInt(productPortalStats.get("active"))); - - // test logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - customerPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - @Test - public void testServletRequestLogout() { - // test login to customer-portal which does a bearer request to customer-db - customerPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(customerPortal); - assertLogged(); - - // test SSO - productPortal.navigateTo(); - assertCurrentUrlEquals(productPortal); - assertPageContains("iPhone"); - assertPageContains("iPad"); - - // back - customerPortal.navigateTo(); - assertCurrentUrlEquals(customerPortal); - assertLogged(); - // test logout - - driver.navigate().to(customerPortal + "/logout"); - WaitUtils.waitUntilElement(By.id("customer_portal_logout")).is().present(); - WaitUtils.waitUntilElement(By.id("customer_database_logout")).is().present(); - - customerPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - @Test - public void testLoginSSOIdle() { - // 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(); - - RealmRepresentation demoRealmRep = testRealmResource().toRepresentation(); - int originalIdle = demoRealmRep.getSsoSessionIdleTimeout(); - try { - demoRealmRep.setSsoSessionIdleTimeout(1); - testRealmResource().update(demoRealmRep); - - // Needs to add some additional time due the tolerance allowed by IDLE_TIMEOUT_WINDOW_SECONDS - setAdapterAndServerTimeOffset(2 + SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS); - - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } finally { - demoRealmRep.setSsoSessionIdleTimeout(originalIdle); - testRealmResource().update(demoRealmRep); - } - } - - @Test - public void testLoginSSOIdleRemoveExpiredUserSessions() { - // test login to customer-portal which does a bearer request to customer-db - customerPortal.navigateTo(); - log.info("Current url: " + driver.getCurrentUrl()); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - log.info("Current url: " + driver.getCurrentUrl()); - assertCurrentUrlEquals(customerPortal); - - RealmRepresentation demoRealmRep = testRealmResource().toRepresentation(); - int originalIdle = demoRealmRep.getSsoSessionIdleTimeout(); - try { - demoRealmRep.setSsoSessionIdleTimeout(1); - testRealmResource().update(demoRealmRep); - - // Needs to add some additional time due the tolerance allowed by IDLE_TIMEOUT_WINDOW_SECONDS - setAdapterAndServerTimeOffset(2 + SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS); - - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } finally { - // need to cleanup so other tests don't fail, so invalidate http sessions on remote clients. - demoRealmRep.setSsoSessionIdleTimeout(originalIdle); - testRealmResource().update(demoRealmRep); - // note: sessions invalidated after each test, see: AbstractKeycloakTest.afterAbstractKeycloakTest() - } - } - - @Test - public void testLoginSSOMax() throws InterruptedException { - // Delete cookies - driver.navigate().to(customerPortal.getUriBuilder().clone().path("error.html").build().toASCIIString()); - driver.manage().deleteAllCookies(); - - // 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); - - RealmRepresentation demoRealmRep = testRealmResource().toRepresentation(); - int originalMax = demoRealmRep.getSsoSessionMaxLifespan(); - try { - demoRealmRep.setSsoSessionMaxLifespan(1); - testRealmResource().update(demoRealmRep); - - TimeUnit.SECONDS.sleep(2); - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } finally { - demoRealmRep.setSsoSessionMaxLifespan(originalMax); - testRealmResource().update(demoRealmRep); - } - } - - //KEYCLOAK-518 - @Test - public void testNullBearerToken() throws Exception { - Client client = createResteasyClient(true, true); - WebTarget target = client.target(customerDb.toString()); - try { - try (Response response = target.request().get()) { - assertEquals(401, response.getStatus()); - } - try (Response response = target.request().header(HttpHeaders.AUTHORIZATION, "Bearer null").get()) { - assertEquals(401, response.getStatus()); - } - } finally { - client.close(); - } - } - - //KEYCLOAK-1368 - @Test - public void testNullBearerTokenCustomErrorPage() throws Exception { - Client client = createResteasyClient(true, true); - WebTarget target = client.target(customerDbErrorPage.toString()); - - try (Response response = target.request().get()) { - assertEquals(401, response.getStatus()); - String errorPageResponse = response.readEntity(String.class); - assertThat(errorPageResponse, containsString("Error Page")); - assertThat(errorPageResponse, containsString("NO_BEARER_TOKEN")); - } - - try (Response response = target.request().header(HttpHeaders.AUTHORIZATION, "Bearer null").get()) { - assertEquals(401, response.getStatus()); - String errorPageResponse = response.readEntity(String.class); - assertThat(errorPageResponse, containsString("Error Page")); - assertThat(errorPageResponse, containsString("INVALID_TOKEN")); - } - - client.close(); - } - - //KEYCLOAK-518 - @Test - public void testBadUser() throws Exception { - Client client = createResteasyClient(true, true); - URI uri = OIDCLoginProtocolService.tokenUrl(authServerPage.createUriBuilder()).build("demo"); - WebTarget target = client.target(uri); - String header = BasicAuthHelper.createHeader("customer-portal", "password"); - Form form = new Form(); - form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD) - .param("username", "monkey@redhat.com") - .param("password", "password"); - try (Response response = target.request() - .header(HttpHeaders.AUTHORIZATION, header) - .post(Entity.form(form))) { - assertEquals(401, response.getStatus()); - } - client.close(); - } - - @Test - public void testAuthenticated() { - // test login to customer-portal which does a bearer request to customer-db - securePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(securePortal); - assertLogged(); - // test logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - securePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - @Test - public void testAuthenticatedWithCustomSessionConfig() { - // test login to customer-portal which does a bearer request to customer-db - securePortalWithCustomSessionConfig.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(securePortalWithCustomSessionConfig); - - assertThat("Cookie CUSTOM_JSESSION_ID_NAME should exist", driver.manage().getCookieNamed("CUSTOM_JSESSION_ID_NAME"), notNullValue()); - - assertLogged(); - // test logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - securePortalWithCustomSessionConfig.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - @Test - public void testRewriteRedirectUri() { - // test login to application where the redirect_uri is rewritten based on rules defined in keycloak.json - securePortalRewriteRedirectUri.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertTrue(driver.getCurrentUrl().contains("/rewritten")); - } - - // Tests "token-minimum-time-to-live" adapter configuration option - @Test - public void testTokenMinTTL() { - // Login - tokenMinTTLPage.navigateTo(); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(tokenMinTTLPage); - - // Get time of token - AccessToken token = tokenMinTTLPage.getAccessToken(); - long tokenIssued1 = token.getIat(); - - // Sets 5 minutes offset and assert access token will be still the same - setAdapterAndServerTimeOffset(300, tokenMinTTLPage.toString()); - tokenMinTTLPage.navigateTo(); - token = tokenMinTTLPage.getAccessToken(); - long tokenIssued2 = token.getIat(); - Assert.assertEquals(tokenIssued1, tokenIssued2); - assertFalse(token.isExpired()); - - // Sets 9 minutes offset and assert access token will be refreshed (accessTokenTimeout is 10 minutes, token-min-ttl is 2 minutes. Hence 8 minutes or more should be sufficient) - setAdapterAndServerTimeOffset(540, tokenMinTTLPage.toString()); - tokenMinTTLPage.navigateTo(); - token = tokenMinTTLPage.getAccessToken(); - long tokenIssued3 = token.getIat(); - Assert.assertTrue(tokenIssued3 > tokenIssued1); - - // Revert times - setAdapterAndServerTimeOffset(0, tokenMinTTLPage.toString()); - } - - @Test - public void testTokenConcurrentRefresh() { - RealmResource demoRealm = adminClient.realm("demo"); - RealmRepresentation demo = demoRealm.toRepresentation(); - - demo.setAccessTokenLifespan(2); - demo.setRevokeRefreshToken(true); - demo.setRefreshTokenMaxReuse(0); - - demoRealm.update(demo); - - // Login - tokenRefreshPage.navigateTo(); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(tokenRefreshPage); - - setAdapterAndServerTimeOffset(5, tokenRefreshPage.toString()); - - BasicCookieStore cookieStore = new BasicCookieStore(); - BasicClientCookie jsessionid = new BasicClientCookie("JSESSIONID", driver.manage().getCookieNamed("JSESSIONID").getValue()); - - jsessionid.setDomain(ServerURLs.APP_SERVER_HOST); - jsessionid.setPath("/"); - cookieStore.addCookie(jsessionid); - - ExecutorService executor = Executors.newWorkStealingPool(); - CompletableFuture future = CompletableFuture.completedFuture(null); - - try { - for (int i = 0; i < 5; i++) { - future = CompletableFuture.allOf(future, CompletableFuture.runAsync(() -> { - try (CloseableHttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore) - .build()) { - HttpUriRequest request = new HttpGet(tokenRefreshPage.getInjectedUrl().toString()); - try (CloseableHttpResponse httpResponse = client.execute(request)) { - assertTrue("Token not refreshed", EntityUtils.toString(httpResponse.getEntity()).contains("accessToken")); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - }, executor)); - } - - future.join(); - } finally { - executor.shutdownNow(); - } - - // Revert times - setAdapterAndServerTimeOffset(0, tokenRefreshPage.toString()); - } - - // Tests forwarding of parameters like "prompt" - @Test - public void testOIDCParamsForwarding() { - // test login to customer-portal which does a bearer request to customer-db - securePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - waitForPageToLoad(); - assertCurrentUrlStartsWith(securePortal); - assertLogged(); - - int currentTime = Time.currentTime(); - try { - setAdapterAndServerTimeOffset(10, securePortal.toString()); - - // Test I need to reauthenticate with prompt=login - String appUri = tokenMinTTLPage.getUriBuilder().queryParam(OIDCLoginProtocol.PROMPT_PARAM, OIDCLoginProtocol.PROMPT_VALUE_LOGIN).build().toString(); - URLUtils.navigateToUri(appUri); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - WaitUtils.waitForPageToLoad(); - testRealmLoginPage.form().setPassword("password"); - testRealmLoginPage.form().login(); - AccessToken token = tokenMinTTLPage.getAccessToken(); - long authTime = token.getAuth_time(); - assertThat(authTime, is(greaterThanOrEqualTo(currentTime + 10L))); - } finally { - setAdapterAndServerTimeOffset(0, securePortal.toString()); - } - } - - private static Map getQueryFromUrl(String url) { - try { - return URLEncodedUtils.parse(new URI(url), StandardCharsets.UTF_8).stream() - .collect(Collectors.toMap(p -> p.getName(), p -> p.getValue())); - } catch (URISyntaxException e) { - return null; - } - } - - @Test - public void testOIDCUiLocalesParamForwarding() { - RealmRepresentation demoRealmRep = testRealmResource().toRepresentation(); - boolean enabled = demoRealmRep.isInternationalizationEnabled(); - String defaultLocale = demoRealmRep.getDefaultLocale(); - Set locales = demoRealmRep.getSupportedLocales(); - demoRealmRep.setInternationalizationEnabled(true); - demoRealmRep.setDefaultLocale("en"); - demoRealmRep.setSupportedLocales(Stream.of("en", "de").collect(Collectors.toSet())); - testRealmResource().update(demoRealmRep); - - try { - // test login with ui_locales to de+en - String portalUri = securePortal.getUriBuilder().build().toString(); - UriBuilder uriBuilder = securePortal.getUriBuilder(); - String appUri = uriBuilder.clone().queryParam(OAuth2Constants.UI_LOCALES_PARAM, "de en").build().toString(); - URLUtils.navigateToUri(appUri); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - // check the ui_locales param is there - Map parameters = getQueryFromUrl(driver.getCurrentUrl()); - assertThat(parameters.get(OAuth2Constants.UI_LOCALES_PARAM), allOf(containsString("de"), containsString("en"))); - - String appUriDe = uriBuilder.clone().queryParam(OAuth2Constants.UI_LOCALES_PARAM, "de").build().toString(); - URLUtils.navigateToUri(appUriDe); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - - // check that the page is in german - assertPageContains("Passwort"); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - // check no ui_locales in the final url adapter url - assertCurrentUrlEquals(portalUri); - assertLogged(); - // logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - securePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } finally { - demoRealmRep.setInternationalizationEnabled(enabled); - demoRealmRep.setDefaultLocale(defaultLocale); - demoRealmRep.setSupportedLocales(locales); - testRealmResource().update(demoRealmRep); - } - } - - - @Test - public void testVerifyTokenAudience() throws Exception { - // Generate audience client scope - String clientScopeId = testingClient.testing().generateAudienceClientScope("demo", "customer-db-audience-required"); - - ClientResource client = ApiUtil.findClientByClientId(adminClient.realm("demo"), "customer-portal"); - client.addOptionalClientScope(clientScopeId); - - // Login without audience scope. Invoke service should end with failure - driver.navigate().to(customerPortal.callCustomerDbAudienceRequiredUrl(false).toURL()); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(customerPortal.callCustomerDbAudienceRequiredUrl(false)); - - String pageSource = driver.getPageSource(); - Assert.assertTrue(pageSource.contains("Service returned: 401")); - Assert.assertFalse(pageSource.contains("Stian Thorgersen")); - - // Logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - - // Login with requested audience - driver.navigate().to(customerPortal.callCustomerDbAudienceRequiredUrl(true).toURL()); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(customerPortal.callCustomerDbAudienceRequiredUrl(false)); - - pageSource = driver.getPageSource(); - Assert.assertFalse(pageSource.contains("Service returned: 401")); - assertLogged(); - - // logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - - @Test - public void testBasicAuth() throws Exception { - String value = "hello"; - Client client = createResteasyClient(true, true); - - //pause(1000000); - - Response response = client.target(basicAuthPage - .setTemplateValues(value).buildUri()).request().header("Authorization", BasicAuthHelper.createHeader("mposolda", "password")).get(); - - assertThat(response, Matchers.statusCodeIs(Status.OK)); - assertEquals(value, response.readEntity(String.class)); - response.close(); - - response = client.target(basicAuthPage - .setTemplateValues(value).buildUri()).request().header("Authorization", BasicAuthHelper.createHeader("invalid-user", "password")).get(); - assertThat(response, Matchers.statusCodeIs(Status.UNAUTHORIZED)); - assertThat(response, Matchers.body(anyOf(containsString("Unauthorized"), containsString("Status 401")))); - - response = client.target(basicAuthPage - .setTemplateValues(value).buildUri()).request().header("Authorization", BasicAuthHelper.createHeader("admin", "invalid-password")).get(); - assertThat(response, Matchers.statusCodeIs(Status.UNAUTHORIZED)); - assertThat(response, Matchers.body(anyOf(containsString("Unauthorized"), containsString("Status 401")))); - - client.close(); - } - - @Test - public void grantServerBasedApp() { - ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "customer-portal"); - ClientRepresentation client = clientResource.toRepresentation(); - client.setConsentRequired(true); - clientResource.update(client); - - RealmRepresentation realm = testRealmResource().toRepresentation(); - realm.setEventsEnabled(true); - realm.setEnabledEventTypes(Arrays.asList("REVOKE_GRANT", "LOGIN")); - realm.setEventsListeners(Arrays.asList("jboss-logging", "event-queue")); - testRealmResource().update(realm); - - customerPortal.navigateTo(); - - loginPage.form().login("bburke@redhat.com", "password"); - - assertTrue(oAuthGrantPage.isCurrent()); - - oAuthGrantPage.accept(); - - waitForPageToLoad(); - assertLogged(); - - String userId = ApiUtil.findUserByUsername(testRealmResource(), "bburke@redhat.com").getId(); - - assertEvents.expectLogin() - .realm(realm.getId()) - .client("customer-portal") - .user(userId) - .detail(Details.USERNAME, "bburke@redhat.com") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .detail(Details.REDIRECT_URI, - org.hamcrest.Matchers.anyOf(org.hamcrest.Matchers.equalTo(customerPortal.getInjectedUrl().toString()), - org.hamcrest.Matchers.equalTo(customerPortal.getInjectedUrl().toString() + "/"))) - .removeDetail(Details.CODE_ID) - .assertEvent(); - - assertEvents.expectCodeToToken(null, null) - .realm(realm.getId()) - .client("customer-portal") - .user(userId) - .session(AssertEvents.isUUID()) - .removeDetail(Details.CODE_ID) - .assertEvent(); - - AccountHelper.revokeConsents(testRealmResource(), "bburke@redhat.com", "customer-portal"); - - customerPortal.navigateTo(); - - assertTrue(oAuthGrantPage.isCurrent()); - - Assert.assertTrue(AccountHelper.getUserConsents(testRealmResource(), "bburke@redhat.com").isEmpty()); - - assertEvents.assertEmpty(); - - // Revert consent - client = clientResource.toRepresentation(); - client.setConsentRequired(false); - clientResource.update(client); - } - - @Test - public void historyOfAccessResourceTest() throws IOException { - RealmRepresentation realm = testRealmResource().toRepresentation(); - realm.setEventsEnabled(true); - realm.setEnabledEventTypes(Arrays.asList("LOGIN", "LOGIN_ERROR", "LOGOUT", "CODE_TO_TOKEN")); - realm.setEventsListeners(Arrays.asList("jboss-logging", "event-queue")); - testRealmResource().update(realm); - - customerPortal.navigateTo(); - - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - - waitForPageToLoad(); - assertLogged(); - - String userId = ApiUtil.findUserByUsername(testRealmResource(), "bburke@redhat.com").getId(); - - assertEvents.expectLogin() - .realm(realm.getId()) - .client("customer-portal") - .user(userId) - .detail(Details.USERNAME, "bburke@redhat.com") - .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) - .detail(Details.REDIRECT_URI, - org.hamcrest.Matchers.anyOf(org.hamcrest.Matchers.equalTo(customerPortal.getInjectedUrl().toString()), - org.hamcrest.Matchers.equalTo(customerPortal.getInjectedUrl().toString() + "/"))) - .removeDetail(Details.CODE_ID) - .assertEvent(); - - assertEvents.expectCodeToToken(null, null) - .realm(realm.getId()) - .client("customer-portal") - .user(userId) - .session(AssertEvents.isUUID()) - .removeDetail(Details.CODE_ID) - .assertEvent(); - - - - String logoutUrl = oauth.realm("demo") - .getLogoutUrl() - .build(); - driver.navigate().to(logoutUrl); - - logoutConfirmPage.assertCurrent(); - logoutConfirmPage.confirmLogout(); - infoPage.assertCurrent(); - driver.navigate().to(customerPortal.toString()); - - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - - assertEvents.expectLogout(null) - .realm(realm.getId()) - .user(userId) - .client("account") - .session(AssertEvents.isUUID()) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); - - assertEvents.assertEmpty(); - - String serverLogPath = null; - - String appServer = System.getProperty("app.server"); - if (appServer != null && (appServer.equals("wildfly") || appServer.equals("eap"))) { - serverLogPath = System.getProperty("app.server.home") + "/standalone-test/log/server.log"; - } - - if (serverLogPath != null) { - log.info("Checking app server log at: " + serverLogPath); - File serverLog = new File(serverLogPath); - String serverLogContent = FileUtils.readFileToString(serverLog, "UTF-8"); - UserRepresentation bburke = ApiUtil.findUserByUsername(testRealmResource(), "bburke@redhat.com"); - - //the expected log message has DEBUG level - assertThat(serverLogContent, containsString("User '" + bburke.getId() + "' invoking '" + ServerURLs.getAppServerContextRoot() + "/customer-db/' on client 'customer-db'")); - } else { - log.info("Checking app server log on app-server: \"" + System.getProperty("app.server") + "\" is not supported."); - } - } - - @Test - public void testWithoutKeycloakConf() { - customerPortalNoConf.navigateTo(); - String pageSource = driver.getPageSource(); - assertThat(pageSource, anyOf(containsString("Forbidden"), containsString("forbidden"), containsString("HTTP Status 401"))); - } - - // KEYCLOAK-3509 - @Test - public void testLoginEncodedRedirectUri() { - // test login to customer-portal which does a bearer request to customer-db - driver.navigate().to(productPortal.getInjectedUrl() + "?encodeTest=a%3Cb"); - System.out.println("Current url: " + driver.getCurrentUrl()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - System.out.println("Current url: " + driver.getCurrentUrl()); - - assertCurrentUrlEquals(productPortal + "?encodeTest=a%3Cb"); - assertPageContains("iPhone"); - assertPageContains("uriEncodeTest=true"); - - driver.navigate().to(productPortal.getInjectedUrl()); - assertCurrentUrlEquals(productPortal); - System.out.println(driver.getCurrentUrl()); - assertPageContains("uriEncodeTest=false"); - - // test logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - driver.navigate().to(oauth.getLoginFormUrl()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - customerPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - - } - - @Test - public void testAutodetectBearerOnly() throws Exception { - Client client = createResteasyClient(true, false); - - // Do not redirect client to login page if it's an XHR - System.out.println(productPortalAutodetectBearerOnly.getInjectedUrl().toString()); - WebTarget target = client.target(productPortalAutodetectBearerOnly.getInjectedUrl().toString() + "/"); - Response response = target.request().header("X-Requested-With", "XMLHttpRequest").get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - // Do not redirect client to login page if it's a partial Faces request - response = target.request().header("Faces-Request", "partial/ajax").get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - // Do not redirect client to login page if it's a SOAP request - response = target.request().header("SOAPAction", "").get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - // Do not redirect client to login page if Accept header is missing - response = target.request().get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - // Do not redirect client to login page if client does not understand HTML reponses - response = target.request().header(HttpHeaders.ACCEPT, "application/json,text/xml").get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - // Redirect client to login page if it's not an XHR - response = target.request().header("X-Requested-With", "Dont-Know").header(HttpHeaders.ACCEPT, "*/*").get(); - Assert.assertEquals(302, response.getStatus()); - assertThat(response.getHeaderString(HttpHeaders.LOCATION), containsString("response_type=code")); - response.close(); - - // Redirect client to login page if client explicitely understands HTML responses - response = target.request().header(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9").get(); - Assert.assertEquals(302, response.getStatus()); - assertThat(response.getHeaderString(HttpHeaders.LOCATION), containsString("response_type=code")); - response.close(); - - // Redirect client to login page if client understands all response types - response = target.request().header(HttpHeaders.ACCEPT, "*/*").get(); - Assert.assertEquals(302, response.getStatus()); - assertThat(response.getHeaderString(HttpHeaders.LOCATION), containsString("response_type=code")); - response.close(); - client.close(); - } - - // KEYCLOAK-3016 - @Test - public void testBasicAuthErrorHandling() throws Exception { - Client client = createResteasyClient(true, true); - WebTarget target = client.target(customerDb.getInjectedUrl().toString()); - Response response = target.request().get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - final int LIMIT = NUMBER_OF_CONNECTIONS + 1; - for (int i = 0; i < LIMIT; i++) { - System.out.println("Testing Basic Auth with bad credentials " + i); - response = target.request().header(HttpHeaders.AUTHORIZATION, "Basic dXNlcm5hbWU6cGFzc3dvcmQ=").get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - } - - client.close(); - } - - // KEYCLOAK-1733 - @Test - public void testNullQueryParameterAccessToken() throws Exception { - Client client = createResteasyClient(true, true); - - WebTarget target = client.target(customerDb.getInjectedUrl().toString()); - Response response = target.request().get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - target = client.target(customerDb.getInjectedUrl().toString() + "?access_token="); - response = target.request().get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - - client.close(); - } - - // KEYCLOAK-1733 - @Test - public void testRestCallWithAccessTokenAsQueryParameter() throws Exception { - - Client client = createResteasyClient(true, true); - try { - WebTarget webTarget = client.target(testRealmPage.toString() + "/protocol/openid-connect/token"); - - Form form = new Form(); - form.param("grant_type", "password"); - form.param("client_id", "customer-portal-public"); - form.param("username", "bburke@redhat.com"); - form.param("password", "password"); - Response response = webTarget.request().post(Entity.form(form)); - - Assert.assertEquals(200, response.getStatus()); - AccessTokenResponse tokenResponse = response.readEntity(AccessTokenResponse.class); - response.close(); - - String accessToken = tokenResponse.getToken(); - - // test without token - response = client.target(customerDb.getInjectedUrl().toString()).request().get(); - Assert.assertEquals(401, response.getStatus()); - response.close(); - // test with access_token as QueryParamter - response = client.target(customerDb.getInjectedUrl().toString()).queryParam("access_token", accessToken).request().get(); - Assert.assertEquals(200, response.getStatus()); - response.close(); - } finally { - client.close(); - } - } - - //KEYCLOAK-4765 - @Test - public void testCallURLWithAccessToken() throws Exception { - // test login to customer-portal which does a bearer request to customer-db - URI applicationURL = inputPortalNoAccessToken.getUriBuilder().clone() - .queryParam("access_token", "invalid_token") - .build(); - - driver.navigate().to(applicationURL.toURL()); - - assertEquals(applicationURL.toASCIIString(), driver.getCurrentUrl()); - inputPortalNoAccessToken.execute("hello"); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - @Test - public void testClientAuthenticatedInClientSecretJwt() { - // test login to customer-portal which does a bearer request to customer-db - // JWS Client Assertion in client_secret_jwt - // http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication - String targetClientId = "client-secret-jwt-secure-portal"; - - expectResultOfClientAuthenticatedInClientSecretJwt(targetClientId, clientSecretJwtSecurePortal); - - // test logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - } - - @Test - public void testClientNotAuthenticatedInClientSecretJwtBySharedSecretOutOfSync() { - // JWS Client Assertion in client_secret_jwt - // http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication - String targetClientId = "client-secret-jwt-secure-portal"; - String expectedErrorString = "invalid_client_credentials"; - - ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), targetClientId); - ClientRepresentation client = clientResource.toRepresentation(); - client.setSecret("passwordChanged"); - clientResource.update(client); - - expectResultOfClientNotAuthenticatedInClientSecretJwt(targetClientId, expectedErrorString); - } - - @Test - public void testClientNotAuthenticatedInClientSecretJwtByAuthnMethodOutOfSync() { - // JWS Client Assertion in client_secret_jwt - // http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication - String targetClientId = "client-secret-jwt-secure-portal"; - String expectedErrorString = "invalid_client_credentials"; - - ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), targetClientId); - ClientRepresentation client = clientResource.toRepresentation(); - client.setClientAuthenticatorType("client-secret"); - clientResource.update(client); - - expectResultOfClientNotAuthenticatedInClientSecretJwt(targetClientId, expectedErrorString); - } - - @Test - public void testClientAuthenticatedInClientSecretJwtValidAlg() { - String targetClientId = "client-secret-jwt-secure-portal-valid-alg"; - - expectResultOfClientAuthenticatedInClientSecretJwt(targetClientId, clientSecretJwtSecurePortalValidAlg); - - // test logout - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - } - - @Test - public void testTokenInCookieSSORoot() { - // Login - String tokenCookie = loginToCustomerCookiePortalRoot(); - Cookie cookie = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE); - assertEquals("/", cookie.getPath()); - - // SSO to second app - customerPortal.navigateTo(); - assertLogged(); - - customerCookiePortalRoot.navigateTo(); - assertLogged(); - cookie = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE); - String tokenCookie2 = cookie.getValue(); - assertEquals(tokenCookie, tokenCookie2); - assertEquals("/", cookie.getPath()); - - // Logout with httpServletRequest - logoutFromCustomerCookiePortalRoot(); - - // Also should be logged-out from the second app - customerPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - private String loginToCustomerCookiePortalRoot() { - customerCookiePortalRoot.navigateTo("relative"); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(customerCookiePortalRoot.getInjectedUrl().toString() + "relative"); - assertLogged(); - - // Assert no JSESSIONID cookie - Assert.assertNull(driver.manage().getCookieNamed("JSESSIONID")); - - return driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue(); - } - - private void logoutFromCustomerCookiePortalRoot() { - String logout = customerCookiePortalRoot.logoutURL(); - driver.navigate().to(logout); - WaitUtils.waitUntilElement(By.id("customer_portal_logout")).is().present(); - assertNull(driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE)); - customerCookiePortalRoot.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - } - - private void expectResultOfClientAuthenticatedInClientSecretJwt(String targetClientId, AbstractPageWithInjectedUrl portal) { - RealmRepresentation realm = testRealmResource().toRepresentation(); - realm.setEventsEnabled(true); - realm.setEnabledEventTypes(Arrays.asList("LOGIN", "CODE_TO_TOKEN")); - realm.setEventsListeners(Arrays.asList("jboss-logging", "event-queue")); - testRealmResource().update(realm); - - portal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - - String userId = ApiUtil.findUserByUsername(testRealmResource(), "bburke@redhat.com").getId(); - - assertEvents.expectLogin() - .realm(realm.getId()) - .client(targetClientId) - .user(userId) - .detail(Details.USERNAME, "bburke@redhat.com") - .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) - .detail(Details.REDIRECT_URI, - org.hamcrest.Matchers.anyOf(org.hamcrest.Matchers.equalTo(portal.getInjectedUrl().toString()), - org.hamcrest.Matchers.equalTo(portal.getInjectedUrl().toString() + "/"))) - .removeDetail(Details.CODE_ID) - .assertEvent(); - - assertEvents.expectCodeToToken(null, null) - .realm(realm.getId()) - .client(targetClientId) - .user(userId) - .session(AssertEvents.isUUID()) - .clearDetails() - .assertEvent(); - } - - private void expectResultOfClientNotAuthenticatedInClientSecretJwt(String targetClientId, String expectedErrorString) { - RealmRepresentation realm = testRealmResource().toRepresentation(); - realm.setEventsEnabled(true); - realm.setEnabledEventTypes(Arrays.asList("LOGIN", "CODE_TO_TOKEN_ERROR")); - realm.setEventsListeners(Arrays.asList("jboss-logging", "event-queue")); - testRealmResource().update(realm); - - clientSecretJwtSecurePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - - String userId = ApiUtil.findUserByUsername(testRealmResource(), "bburke@redhat.com").getId(); - - assertEvents.expectLogin() - .realm(realm.getId()) - .client(targetClientId) - .user(userId) - .detail(Details.USERNAME, "bburke@redhat.com") - .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) - .detail(Details.REDIRECT_URI, - org.hamcrest.Matchers.anyOf(org.hamcrest.Matchers.equalTo(clientSecretJwtSecurePortal.getInjectedUrl().toString()), - org.hamcrest.Matchers.equalTo(clientSecretJwtSecurePortal.getInjectedUrl().toString() + "/"))) - .removeDetail(Details.CODE_ID) - .assertEvent(); - - assertEvents.expectCodeToToken(null, null) - .realm(realm.getId()) - .client(targetClientId) - .user((String)null) - .error(expectedErrorString) - .clearDetails() - .assertEvent(); - } - - @Test - public void testLoginHintFromClientRequest() { - driver.navigate().to(customerPortal + "?login_hint=blah%3d"); - waitForPageToLoad(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - assertThat(testRealmLoginPage.form().getUsername(), is("blah=")); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/KeycloakPrincipalSerializationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/KeycloakPrincipalSerializationTest.java deleted file mode 100644 index 4edca30e84..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/KeycloakPrincipalSerializationTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.keycloak.testsuite.adapter.servlet; - -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.Test; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.page.SerializationServletPage; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.utils.arquillian.ContainerConstants; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.MatcherAssert.assertThat; - - -@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW) -// The purpose of this class is to test KeycloakPrincipal serialization on different app-server-jdks -public class KeycloakPrincipalSerializationTest extends AbstractServletsAdapterTest { - @Page - protected SerializationServletPage serializationServlet; - - @Deployment(name = SerializationServletPage.DEPLOYMENT_NAME) - protected static WebArchive serializationServlet() { - return servletDeployment(SerializationServletPage.DEPLOYMENT_NAME, SerializationServlet.class, ErrorServlet.class, ServletTestUtils.class); - } - - @Test - public void testKeycloakPrincipalSerialization() { - serializationServlet.navigateTo(); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - - assertThat(driver.getPageSource(), containsString("Serialization/Deserialization was successful")); - assertThat(driver.getPageSource(), not(containsString("Context was not instance of RefreshableKeycloakSecurityContext"))); - assertThat(driver.getPageSource(), not(containsString("Deserialization failed"))); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/MultiTenancyTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/MultiTenancyTest.java deleted file mode 100644 index 4d8806611b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/MultiTenancyTest.java +++ /dev/null @@ -1,160 +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.servlet; - -import java.net.URL; -import java.util.List; -import jakarta.ws.rs.core.UriBuilder; -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.After; -import org.junit.Assert; -import org.junit.Test; -import org.keycloak.protocol.oidc.OIDCLoginProtocolService; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.page.MultiTenant; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.utils.arquillian.ContainerConstants; -import org.keycloak.testsuite.util.URLAssert; -import org.keycloak.testsuite.util.WaitUtils; - -import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm; - -/** - * note: migrated from old testsuite - * - * @author Juraci Paixão Kröhling - */ -@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW) -public class MultiTenancyTest extends AbstractServletsAdapterTest { - - @Page - private MultiTenant tenantPage; - - @Override - public void addAdapterTestRealms(List testRealms) { - testRealms.add(loadRealm("/adapter-test/tenant1-realm.json")); - testRealms.add(loadRealm("/adapter-test/tenant2-realm.json")); - } - - @Override - protected boolean isImportAfterEachMethod() { - return false; - } - - @Deployment(name = MultiTenant.DEPLOYMENT_NAME) - protected static WebArchive multiTenant() { - return servletDeploymentMultiTenant(MultiTenant.DEPLOYMENT_NAME, MultiTenantServlet.class, ErrorServlet.class, MultiTenantResolver.class); - } - - @After - public void afterTest() { - driver.manage().deleteAllCookies(); - } - - /** - * Simplest scenario: one user, one realm. The user is not logged in at - * any other realm - */ - @Test - public void testTenantsLoggingOut() { - doTenantRequests("tenant1", true); - doTenantRequests("tenant2", true); - } - - /** - * This tests the adapter's ability to deal with multiple sessions - * from the same user, one for each realm. It should not mixup and return - * a session from tenant1 to tenant2 - */ - @Test - public void testTenantsWithoutLoggingOut() { - doTenantRequests("tenant1", true); - doTenantRequests("tenant2", true); - - doTenantRequests("tenant1", false); - doTenantRequests("tenant2", true); - - logout("tenant1"); - } - - /** - * This test simulates an user that is not logged in yet, and tries to login - * into tenant1 using an account from tenant2. - * On this scenario, the user should be shown the login page again. - */ - @Test - public void testUnauthorizedAccessNotLoggedIn() { - String keycloakServerBaseUrl = authServerPage.toString(); - - driver.navigate().to(tenantPage.getTenantRealmUrl("tenant1")); - WaitUtils.waitForPageToLoad(); - URLAssert.assertCurrentUrlStartsWith(keycloakServerBaseUrl); - - testRealmLoginPage.form().login("user-tenant2", "user-tenant2"); - URLAssert.assertCurrentUrlStartsWith(keycloakServerBaseUrl); - } - - /** - * This test simulates an user which is already logged in into tenant1 - * and tries to access a resource on tenant2. - * On this scenario, the user should be shown the login page again. - */ - @Test - public void testUnauthorizedAccessLoggedIn() { - doTenantRequests("tenant1", false); - - driver.navigate().to(tenantPage.getTenantRealmUrl("tenant2")); - URLAssert.assertCurrentUrlStartsWith(authServerPage.toString()); - - logout("tenant1"); - } - - private void doTenantRequests(String tenant, boolean logout) { - String tenantLoginUrl = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(authServerPage.getAuthRoot())).build(tenant).toString(); - URL tenantUrl = tenantPage.getTenantRealmUrl(tenant); - - driver.navigate().to(tenantUrl); - URLAssert.assertCurrentUrlStartsWith(tenantLoginUrl); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - log.debug("Current url: " + driver.getCurrentUrl()); - - URLAssert.assertCurrentUrlStartsWith(tenantUrl.toString()); - String pageSource = driver.getPageSource(); - log.debug(pageSource); - - Assert.assertTrue(pageSource.contains("Username: bburke@redhat.com")); - Assert.assertTrue(pageSource.contains("Realm: " + tenant)); - - if (logout) { - driver.navigate().to(tenantUrl + "/logout"); - Assert.assertFalse(driver.getPageSource().contains("Username: bburke@redhat.com")); - Assert.assertTrue(driver.getCurrentUrl().startsWith(tenantLoginUrl)); - } - log.debug("---------------------------------------------------------------------------------------"); - } - - private void logout(String tenant) { - String tenantLoginUrl = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(authServerPage.getAuthRoot())).build(tenant).toString(); - URL tenantUrl = tenantPage.getTenantRealmUrl(tenant); - driver.navigate().to(tenantUrl + "/logout"); - Assert.assertFalse(driver.getPageSource().contains("Username: bburke@redhat.com")); - Assert.assertTrue(driver.getCurrentUrl().startsWith(tenantLoginUrl)); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/OIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/OIDCPublicKeyRotationAdapterTest.java deleted file mode 100644 index a457eaf9be..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/OIDCPublicKeyRotationAdapterTest.java +++ /dev/null @@ -1,355 +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 java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.concurrent.TimeUnit; - -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriBuilder; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -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.Before; -import org.junit.Test; -import org.keycloak.admin.client.resource.ClientResource; -import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.common.util.StreamUtil; -import org.keycloak.common.util.Time; -import org.keycloak.constants.AdapterConstants; -import org.keycloak.crypto.Algorithm; -import org.keycloak.crypto.KeyUse; -import org.keycloak.keys.KeyProvider; -import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; -import org.keycloak.representations.AccessToken; -import org.keycloak.representations.adapters.action.GlobalRequestResult; -import org.keycloak.representations.idm.ClientRepresentation; -import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.KeysMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; -import org.keycloak.testsuite.adapter.page.CustomerDb; -import org.keycloak.testsuite.adapter.page.SecurePortal; -import org.keycloak.testsuite.adapter.page.TokenMinTTLPage; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.util.KeyUtils; -import org.keycloak.testsuite.utils.arquillian.ContainerConstants; -import org.keycloak.testsuite.util.URLAssert; -import org.openqa.selenium.By; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; -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.waitUntilElement; - -/** - * Tests related to public key rotation for OIDC adapter - * - * @author Marek Posolda - */ -@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW) -public class OIDCPublicKeyRotationAdapterTest extends AbstractServletsAdapterTest { - - @Page - private SecurePortal securePortal; - - @Page - private TokenMinTTLPage tokenMinTTLPage; - - @Page - private CustomerDb customerDb; - - @Deployment(name = SecurePortal.DEPLOYMENT_NAME) - protected static WebArchive securePortal() { - return servletDeployment(SecurePortal.DEPLOYMENT_NAME, AdapterActionsFilter.class, CallAuthenticatedServlet.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 = CustomerDb.DEPLOYMENT_NAME) - protected static WebArchive customerDb() { - return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class); - } - - - @Before - public void beforeRotationAdapterTest() { - // Delete all cookies from token-min-ttl page to be sure we are logged out - tokenMinTTLPage.navigateTo(); - driver.manage().deleteAllCookies(); - } - - - @Test - public void testRealmKeyRotationWithNewKeyDownload() throws Exception { - // Login success first - loginToTokenMinTtlApp(); - - // Logout - ApiUtil.findUserByUsernameId(adminClient.realm("demo"), "bburke@redhat.com").logout(); - - // Generate new realm keys - generateNewRealmKey(KeyUse.SIG); - generateNewRealmKey(KeyUse.ENC); - - // Try to login again. It should fail now because not yet allowed to download new keys - tokenMinTTLPage.navigateTo(); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - URLAssert.assertCurrentUrlStartsWith(tokenMinTTLPage.getInjectedUrl().toString()); - - ApiUtil.findUserByUsernameId(adminClient.realm("demo"), "bburke@redhat.com").logout(); - - setAdapterAndServerTimeOffset(300, tokenMinTTLPage.toString() + "/unsecured/foo"); - - // Try to login. Should work now due to realm key change - loginToTokenMinTtlApp(); - ApiUtil.findUserByUsernameId(adminClient.realm("demo"), "bburke@redhat.com").logout(); - - // Revert public keys change - resetKeycloakDeploymentForAdapter(tokenMinTTLPage.toString() + "/unsecured/foo"); - } - - - @Test - public void testClientWithJwksUri() throws Exception { - // Set client to bad JWKS URI - ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "secure-portal"); - ClientRepresentation client = clientResource.toRepresentation(); - OIDCAdvancedConfigWrapper wrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client); - wrapper.setUseJwksUrl(true); - wrapper.setJwksUrl(securePortal + "/bad-jwks-url"); - clientResource.update(client); - - // Login should fail at the code-to-token - securePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - String pageSource = driver.getPageSource(); - assertCurrentUrlStartsWith(securePortal); - assertFalse(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen")); - - // Set client to correct JWKS URI - client = clientResource.toRepresentation(); - wrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client); - wrapper.setUseJwksUrl(true); - wrapper.setJwksUrl(securePortal + "/" + AdapterConstants.K_JWKS); - clientResource.update(client); - - // Login to secure-portal should be fine now. Client keys downloaded from JWKS URI - securePortal.navigateTo(); - assertCurrentUrlEquals(securePortal); - pageSource = driver.getPageSource(); - assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen")); - - // Logout - ApiUtil.findUserByUsernameId(adminClient.realm("demo"), "bburke@redhat.com").logout(); - } - - - // KEYCLOAK-3824: Test for public-key-cache-ttl - @Test - public void testPublicKeyCacheTtl() { - String customerDBUnsecuredUrl = customerDb.getUriBuilder().clone().path("unsecured").path("foo").build().toASCIIString(); - String tokenMinTTLUnsecuredUrl = tokenMinTTLPage.getUriBuilder().clone().path("unsecured").path("foo").build().toASCIIString(); - - // increase accessTokenLifespan to 1200 - RealmRepresentation demoRealm = adminClient.realm(DEMO).toRepresentation(); - demoRealm.setAccessTokenLifespan(1200); - adminClient.realm(DEMO).update(demoRealm); - - // authenticate in tokenMinTTL app - loginToTokenMinTtlApp(); - String accessTokenString = tokenMinTTLPage.getAccessTokenString(); - - // Send REST request to customer-db app. I should be successfully authenticated - int status = invokeRESTEndpoint(accessTokenString); - Assert.assertEquals(200, status); - - // Re-generate realm public key and remove the old key (for both sig and enc) - String oldActiveKeyProviderId = getActiveKeyProviderId(KeyUse.SIG); - generateNewRealmKey(KeyUse.SIG); - adminClient.realm(DEMO).components().component(oldActiveKeyProviderId).remove(); - oldActiveKeyProviderId = getActiveKeyProviderId(KeyUse.ENC); - generateNewRealmKey(KeyUse.ENC); - adminClient.realm(DEMO).components().component(oldActiveKeyProviderId).remove(); - - // Send REST request to the customer-db app. Should be still succcessfully authenticated as the JWKPublicKeyLocator cache is still valid - status = invokeRESTEndpoint(accessTokenString); - Assert.assertEquals(200, status); - - // TimeOffset to 900 on the REST app side. Token is still valid (1200) but JWKPublicKeyLocator should try to download new key (public-key-cache-ttl=600) - setAdapterAndServerTimeOffset(900, customerDBUnsecuredUrl, tokenMinTTLUnsecuredUrl); - - // Send REST request. New request to the publicKey cache should be sent, and key is no longer returned as token contains the old kid - status = invokeRESTEndpoint(accessTokenString); - Assert.assertEquals(401, status); - - // Revert public keys change and time offset - resetKeycloakDeploymentForAdapter(customerDBUnsecuredUrl); - resetKeycloakDeploymentForAdapter(tokenMinTTLUnsecuredUrl); - } - - - // KEYCLOAK-3823: Test that sending notBefore policy invalidates JWKPublicKeyLocator cache - @Test - public void testPublicKeyCacheInvalidatedWhenPushedNotBefore() { - driver.manage().timeouts().pageLoadTimeout(1000, TimeUnit.SECONDS); - String customerDBUnsecuredUrl = customerDb.getUriBuilder().clone().path("unsecured").path("foo").build().toASCIIString(); - String customerDBUrlNoTrailSlash = customerDb.getUriBuilder().build().toASCIIString(); - customerDBUrlNoTrailSlash = customerDBUrlNoTrailSlash.substring(0, customerDBUrlNoTrailSlash.length() - 1); - String tokenMinTTLUnsecuredUrl = tokenMinTTLPage.getUriBuilder().clone().path("unsecured").path("foo").build().toASCIIString(); - - // increase accessTokenLifespan to 1200 - RealmRepresentation demoRealm = adminClient.realm(DEMO).toRepresentation(); - demoRealm.setAccessTokenLifespan(1200); - adminClient.realm(DEMO).update(demoRealm); - - // authenticate in tokenMinTTL app - loginToTokenMinTtlApp(); - String accessTokenString = tokenMinTTLPage.getAccessTokenString(); - - // Generate new realm public key - String oldActiveSigKeyProviderId = getActiveKeyProviderId(KeyUse.SIG); - generateNewRealmKey(KeyUse.SIG); - String oldActiveEncKeyProviderId = getActiveKeyProviderId(KeyUse.ENC); - generateNewRealmKey(KeyUse.ENC); - - // Send REST request to customer-db app. It should be successfully authenticated even that token is signed by the old key - int status = invokeRESTEndpoint(accessTokenString); - Assert.assertEquals(200, status); - - // Remove the old realm keys now - adminClient.realm(DEMO).components().component(oldActiveSigKeyProviderId).remove(); - adminClient.realm(DEMO).components().component(oldActiveEncKeyProviderId).remove(); - - // Set some offset to ensure pushing notBefore will pass - setAdapterAndServerTimeOffset(130, customerDBUnsecuredUrl, tokenMinTTLUnsecuredUrl); - - // Send notBefore policy from the realm - demoRealm.setNotBefore(Time.currentTime() - 1); - adminClient.realm(DEMO).update(demoRealm); - GlobalRequestResult result = adminClient.realm(DEMO).pushRevocation(); - Assert.assertTrue(result.getSuccessRequests().contains(customerDBUrlNoTrailSlash)); - - // Send REST request. New request to the publicKey cache should be sent, and key is no longer returned as token contains the old kid - status = invokeRESTEndpoint(accessTokenString); - Assert.assertEquals(401, status); - - // Revert public keys change and time offset - resetKeycloakDeploymentForAdapter(customerDBUnsecuredUrl); - resetKeycloakDeploymentForAdapter(tokenMinTTLUnsecuredUrl); - } - - - // HELPER METHODS - - private void loginToTokenMinTtlApp() { - tokenMinTTLPage.navigateTo(); - assertTrue(testRealmLoginPage.form().isUsernamePresent()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(tokenMinTTLPage); - - AccessToken token = tokenMinTTLPage.getAccessToken(); - Assert.assertEquals("bburke@redhat.com", token.getPreferredUsername()); - } - - - private void generateNewRealmKey(KeyUse keyUse) { - String realmId = adminClient.realm(DEMO).toRepresentation().getId(); - - ComponentRepresentation keys = new ComponentRepresentation(); - keys.setName("generated"); - keys.setProviderType(KeyProvider.class.getName()); - keys.setProviderId(keyUse == KeyUse.SIG ? "rsa-generated" : "rsa-enc-generated"); - keys.setParentId(realmId); - keys.setConfig(new MultivaluedHashMap<>()); - keys.getConfig().putSingle("priority", "150"); - keys.getConfig().putSingle("keyUse", keyUse.getSpecName()); - Response response = adminClient.realm(DEMO).components().add(keys); - assertEquals(201, response.getStatus()); - response.close(); - } - - private String getActiveKeyProviderId(KeyUse keyUse) { - KeysMetadataRepresentation.KeyMetadataRepresentation key = keyUse == KeyUse.ENC - ? KeyUtils.findActiveEncryptingKey(adminClient.realm(DEMO), Algorithm.RSA_OAEP) - : KeyUtils.findActiveSigningKey(adminClient.realm(DEMO), Algorithm.RS256); - - return key != null ? key.getProviderId() : null; - } - - private int invokeRESTEndpoint(String accessTokenString) { - - try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - String restUrl = customerDb.toString(); - HttpGet get = new HttpGet(restUrl); - get.addHeader("Authorization", "Bearer " + accessTokenString); - try { - HttpResponse response = client.execute(get); - int status = response.getStatusLine().getStatusCode(); - if (status != 200) { - return status; - } - - HttpEntity entity = response.getEntity(); - try (InputStream is = entity.getContent()) { - String body = StreamUtil.readString(is, Charset.forName("UTF-8")); - Assert.assertTrue(body.contains("Stian Thorgersen") && body.contains("Bill Burke")); - return status; - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - - private void resetKeycloakDeploymentForAdapter(String adapterActionsUrl) { - String timeOffsetUri = UriBuilder.fromUri(adapterActionsUrl) - .queryParam(AdapterActionsFilter.RESET_DEPLOYMENT_PARAM, "true") - .build().toString(); - driver.navigate().to(timeOffsetUri); - waitUntilElement(By.tagName("body")).is().visible(); - } - - -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/OfflineServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/OfflineServletsAdapterTest.java deleted file mode 100644 index e87a19c057..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/OfflineServletsAdapterTest.java +++ /dev/null @@ -1,275 +0,0 @@ -package org.keycloak.testsuite.adapter.servlet; - -import jakarta.ws.rs.core.UriBuilder; -import java.util.List; -import java.util.Map; -import java.util.LinkedHashMap; -import java.util.ArrayList; - -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.Test; -import org.keycloak.OAuth2Constants; -import org.keycloak.representations.RefreshToken; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; -import org.keycloak.testsuite.adapter.page.OfflineToken; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.updaters.ClientAttributeUpdater; -import org.keycloak.testsuite.util.AccountHelper; -import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; -import org.keycloak.testsuite.util.WaitUtils; -import org.keycloak.testsuite.utils.arquillian.ContainerConstants; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.pages.OAuthGrantPage; -import org.keycloak.testsuite.utils.io.IOUtil; -import org.keycloak.util.TokenUtil; -import org.openqa.selenium.By; - -import java.io.Closeable; -import java.io.IOException; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; -import static org.keycloak.testsuite.util.WaitUtils.pause; -import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad; -import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; - -/** - * @author Bruno Oliveira. - */ -@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW) -public class OfflineServletsAdapterTest extends AbstractServletsAdapterTest { - - @Rule - public AssertEvents events = new AssertEvents(this); - @Page - protected OfflineToken offlineTokenPage; - @Page - protected LoginPage loginPage; - @Page - protected OAuthGrantPage oauthGrantPage; - - @Rule - public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); - - private final String DEFAULT_USERNAME = "test-user@localhost"; - private final String DEFAULT_PASSWORD = "password"; - private final String OFFLINE_CLIENT_ID = "offline-client"; - - /** - * URL in the deployment that doesn't require authentication and which therefore can be used to trigger activities in the actionfilter. - */ - private static final String UNSECURED_URL = "unsecured/foo"; - - @Deployment(name = OfflineToken.DEPLOYMENT_NAME) - protected static WebArchive offlineClient() { - return servletDeployment(OfflineToken.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, OfflineTokenServlet.class, ErrorServlet.class, ServletTestUtils.class); - } - - @Override - public void setDefaultPageUriParameters() { - super.setDefaultPageUriParameters(); - testRealmPage.setAuthRealm(TEST); - testRealmLoginPage.setAuthRealm(TEST); - } - - - @Override - public void addAdapterTestRealms(List testRealms) { - testRealms.add(IOUtil.loadRealm("/adapter-test/offline-client/offlinerealm.json")); - } - - @Override - protected boolean isImportAfterEachMethod() { - // For proper cleanup of test methods - return true; - } - - @Test - public void testServlet() { - try { - String servletUri = UriBuilder.fromUri(offlineTokenPage.toString()) - .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS) - .build().toString(); - oauth.redirectUri(offlineTokenPage.toString()); - oauth.clientId("offline-client"); - - driver.navigate().to(servletUri); - waitUntilElement(By.tagName("body")).is().visible(); - - loginPage.assertCurrent(); - loginPage.login(DEFAULT_USERNAME, DEFAULT_PASSWORD); - - assertCurrentUrlStartsWith(offlineTokenPage); - - RefreshToken refreshToken = offlineTokenPage.getRefreshToken(); - assertThat(TokenUtil.TOKEN_TYPE_OFFLINE, is(refreshToken.getType())); - assertThat(refreshToken.getExp(), nullValue()); - - String accessTokenId = offlineTokenPage.getAccessToken().getId(); - String refreshTokenId = refreshToken.getId(); - - // online user session will be expired and removed - setAdapterAndServerTimeOffset(9999); - - // still able to access the page using the offline token - offlineTokenPage.navigateTo(); - assertCurrentUrlStartsWith(offlineTokenPage); - - // assert successful refresh - assertThat(offlineTokenPage.getRefreshToken().getId(), not(refreshTokenId)); - assertThat(offlineTokenPage.getAccessToken().getId(), not(accessTokenId)); - - // logout doesn't make sense because online user session is gone and there is no KEYCLOAK_IDENTITY / KEYCLOAK_SESSION cookie in the browser - // navigate to login page which won't be possible if there's valid online session - driver.navigate().to(oauth.getLoginFormUrl()); - WaitUtils.waitForPageToLoad(); - loginPage.assertCurrent(); - - // navigate back to offlineTokenPage to verify the offline session is still valid - offlineTokenPage.navigateTo(); - assertCurrentUrlStartsWith(offlineTokenPage); - - // logout the offline user session using the offline refresh token - oauth.doLogout(offlineTokenPage.getRefreshTokenString(), "secret1"); - - // can't access the offlineTokenPage anymore - offlineTokenPage.navigateTo(); - assertCurrentUrlDoesntStartWith(offlineTokenPage); - loginPage.assertCurrent(); - } finally { - events.clear(); - resetTimeOffset(); - } - } - - @Test - public void testServletWithRevoke() { - try { // Login to servlet first with offline token - String servletUri = UriBuilder.fromUri(offlineTokenPage.toString()) - .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS) - .build().toString(); - - driver.navigate().to(servletUri); - waitUntilElement(By.tagName("body")).is().visible(); - - loginPage.assertCurrent(); - loginPage.login(DEFAULT_USERNAME, DEFAULT_PASSWORD); - assertCurrentUrlStartsWith(offlineTokenPage); - - final RefreshToken refreshToken = offlineTokenPage.getRefreshToken(); - assertThat(refreshToken.getType(), is(TokenUtil.TOKEN_TYPE_OFFLINE)); - - // Assert refresh works with increased time - setAdapterAndServerTimeOffset(9999); - offlineTokenPage.navigateTo(); - assertCurrentUrlStartsWith(offlineTokenPage); - setAdapterAndServerTimeOffset(0); - - events.clear(); - - // Check that Offline Token is granted - List> userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); - String actualValue = String.valueOf(((LinkedHashMap) ((ArrayList) userConsents.get(0).get("additionalGrants")).get(0)).get("key")); - Assert.assertEquals("Offline Token", actualValue); - - // Revoke consents - AccountHelper.revokeConsents(adminClient.realm(TEST), DEFAULT_USERNAME, OFFLINE_CLIENT_ID); - pause(500); - - userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); - assertThat(userConsents.size(), is(0)); - - // Assert refresh doesn't work now (increase time one more time) - setAdapterAndServerTimeOffset(19999); - offlineTokenPage.navigateTo(); - assertCurrentUrlDoesntStartWith(offlineTokenPage); - loginPage.assertCurrent(); - } finally { - events.clear(); - resetTimeOffset(); - } - } - - @Test - public void testServletWithConsent() throws IOException { - try (Closeable cau = ClientAttributeUpdater.forClient(adminClient, TEST, OFFLINE_CLIENT_ID) - .setConsentRequired(true).update()) { - - // Assert grant page doesn't have 'Offline Access' role when offline token is not requested - offlineTokenPage.navigateTo(); - - loginPage.assertCurrent(); - loginPage.login(DEFAULT_USERNAME, DEFAULT_PASSWORD); - - oauthGrantPage.assertCurrent(); - waitUntilElement(By.xpath("//body")).text().not().contains("Offline access"); - oauthGrantPage.cancel(); - - // Assert grant page has 'Offline Access' role now - String servletUri = UriBuilder.fromUri(offlineTokenPage.toString()) - .queryParam(OAuth2Constants.SCOPE, OAuth2Constants.OFFLINE_ACCESS) - .build().toString(); - driver.navigate().to(servletUri); - waitUntilElement(By.tagName("body")).is().visible(); - - loginPage.login(DEFAULT_USERNAME, DEFAULT_PASSWORD); - oauthGrantPage.assertCurrent(); - waitUntilElement(By.xpath("//body")).text().contains(OAuthGrantPage.OFFLINE_ACCESS_CONSENT_TEXT); - - oauthGrantPage.accept(); - - assertCurrentUrlStartsWith(offlineTokenPage); - - RefreshToken refreshToken = offlineTokenPage.getRefreshToken(); - assertThat(refreshToken.getType(), is(TokenUtil.TOKEN_TYPE_OFFLINE)); - - // Check that the client scopes have been granted by the user - List> userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); - Assert.assertTrue(((List) userConsents.get(0).get("grantedClientScopes")).stream().anyMatch(p -> p.equals("offline_access"))); - String actualValue = String.valueOf(((LinkedHashMap) ((ArrayList) userConsents.get(0).get("additionalGrants")).get(0)).get("key")); - Assert.assertEquals("Offline Token", actualValue); - - AccountHelper.logout(adminClient.realm(TEST), DEFAULT_USERNAME); - } finally { - events.clear(); - resetTimeOffset(); - } - } - - private void setAdapterAndServerTimeOffset(int timeOffset) { - super.setAdapterAndServerTimeOffset(timeOffset, offlineTokenPage.toString() + UNSECURED_URL); - } - - @Override - public void resetTimeOffset() { - setAdapterServletTimeOffset(0, offlineTokenPage.toString() + UNSECURED_URL); - super.resetTimeOffset(); - } - - @Override - protected void afterAbstractKeycloakTestRealmImport() { - // after each re-import, ensure that the information stored in JWKPublicKeyLocator is reset - String resetDeploymentUri = UriBuilder.fromUri(offlineTokenPage.toString() + UNSECURED_URL) - .queryParam(AdapterActionsFilter.RESET_DEPLOYMENT_PARAM, "true") - .build().toString(); - driver.navigate().to(resetDeploymentUri); - waitForPageToLoad(); - - assertThat(driver.getPageSource(), containsString("Restarted PublicKeyLocator")); - super.afterAbstractKeycloakTestRealmImport(); - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLClockSkewAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLClockSkewAdapterTest.java index 988f4782eb..c35c539afe 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLClockSkewAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLClockSkewAdapterTest.java @@ -25,9 +25,9 @@ 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.Test; -import org.keycloak.adapters.rotation.PublicKeyLocator; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; +import org.keycloak.testsuite.adapter.page.SalesPostClockSkewServlet; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.util.SamlClientBuilder; import org.keycloak.testsuite.utils.arquillian.ContainerConstants; @@ -39,7 +39,6 @@ import static org.hamcrest.Matchers.not; import org.jboss.arquillian.graphene.page.Page; import static org.hamcrest.MatcherAssert.assertThat; -import org.keycloak.testsuite.adapter.page.SalesPostClockSkewServlet; import static org.keycloak.testsuite.util.SamlClient.Binding.POST; @@ -57,16 +56,16 @@ public class SAMLClockSkewAdapterTest extends AbstractSAMLServletAdapterTest { @Deployment(name = DEPLOYMENT_NAME_3_SEC, managed = false) protected static WebArchive salesPostClockSkewServlet3Sec() { - return samlServletDeployment(SalesPostClockSkewServlet.DEPLOYMENT_NAME, DEPLOYMENT_NAME_3_SEC, SalesPostClockSkewServlet.DEPLOYMENT_NAME + "/WEB-INF/web.xml", 3, AdapterActionsFilter.class, PublicKeyLocator.class, SendUsernameServlet.class); + return samlServletDeployment(SalesPostClockSkewServlet.DEPLOYMENT_NAME, DEPLOYMENT_NAME_3_SEC, SalesPostClockSkewServlet.DEPLOYMENT_NAME + "/WEB-INF/web.xml", 3, AdapterActionsFilter.class, SendUsernameServlet.class); } @Deployment(name = DEPLOYMENT_NAME_30_SEC, managed = false) protected static WebArchive salesPostClockSkewServlet30Sec() { - return samlServletDeployment(SalesPostClockSkewServlet.DEPLOYMENT_NAME, DEPLOYMENT_NAME_30_SEC, SalesPostClockSkewServlet.DEPLOYMENT_NAME + "/WEB-INF/web.xml", 30, AdapterActionsFilter.class, PublicKeyLocator.class, SendUsernameServlet.class); + return samlServletDeployment(SalesPostClockSkewServlet.DEPLOYMENT_NAME, DEPLOYMENT_NAME_30_SEC, SalesPostClockSkewServlet.DEPLOYMENT_NAME + "/WEB-INF/web.xml", 30, AdapterActionsFilter.class, SendUsernameServlet.class); } @Deployment(name = SalesPostClockSkewServlet.DEPLOYMENT_NAME, managed = false) protected static WebArchive salesPostClockSkewServlet5Sec() { - return samlServletDeployment(SalesPostClockSkewServlet.DEPLOYMENT_NAME, SalesPostClockSkewServlet.DEPLOYMENT_NAME + "/WEB-INF/web.xml", 5, AdapterActionsFilter.class, PublicKeyLocator.class, SendUsernameServlet.class); + return samlServletDeployment(SalesPostClockSkewServlet.DEPLOYMENT_NAME, SalesPostClockSkewServlet.DEPLOYMENT_NAME + "/WEB-INF/web.xml", 5, AdapterActionsFilter.class, SendUsernameServlet.class); } @Override diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLLoginResponseHandlingTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLLoginResponseHandlingTest.java index 5114303c22..9007e65550 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLLoginResponseHandlingTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLLoginResponseHandlingTest.java @@ -5,7 +5,6 @@ import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; -import org.keycloak.adapters.rotation.PublicKeyLocator; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.dom.saml.v2.assertion.AttributeStatementType; @@ -68,7 +67,7 @@ public class SAMLLoginResponseHandlingTest extends AbstractSAMLServletAdapterTes @Deployment(name = Employee2Servlet.DEPLOYMENT_NAME) protected static WebArchive employee2() { - return samlServletDeployment(Employee2Servlet.DEPLOYMENT_NAME, WEB_XML_WITH_ACTION_FILTER, SendUsernameServlet.class, AdapterActionsFilter.class, PublicKeyLocator.class); + return samlServletDeployment(Employee2Servlet.DEPLOYMENT_NAME, WEB_XML_WITH_ACTION_FILTER, SendUsernameServlet.class, AdapterActionsFilter.class); } @Deployment(name = EmployeeSigServlet.DEPLOYMENT_NAME) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletSessionTimeoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletSessionTimeoutTest.java index 584fe0728a..25d5e92a64 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletSessionTimeoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletSessionTimeoutTest.java @@ -4,7 +4,6 @@ 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.Test; -import org.keycloak.adapters.rotation.PublicKeyLocator; import org.keycloak.dom.saml.v2.SAML2Object; import org.keycloak.dom.saml.v2.assertion.AuthnStatementType; import org.keycloak.dom.saml.v2.assertion.StatementAbstractType; @@ -44,7 +43,7 @@ public class SAMLServletSessionTimeoutTest extends AbstractSAMLServletAdapterTes @Deployment(name = Employee2Servlet.DEPLOYMENT_NAME) protected static WebArchive employee2() { - return samlServletDeployment(Employee2Servlet.DEPLOYMENT_NAME, WEB_XML_WITH_ACTION_FILTER, SendUsernameServlet.class, AdapterActionsFilter.class, PublicKeyLocator.class); + return samlServletDeployment(Employee2Servlet.DEPLOYMENT_NAME, WEB_XML_WITH_ACTION_FILTER, SendUsernameServlet.class, AdapterActionsFilter.class); } private static final int SESSION_LENGTH_IN_SECONDS = 120; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SessionServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SessionServletAdapterTest.java deleted file mode 100644 index 30372be749..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SessionServletAdapterTest.java +++ /dev/null @@ -1,225 +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.hamcrest.MatcherAssert; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.drone.api.annotation.Drone; -import org.jboss.arquillian.graphene.page.Page; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.After; -import org.junit.Test; -import org.keycloak.admin.client.resource.ClientResource; -import org.keycloak.protocol.oidc.OIDCLoginProtocolService; -import org.keycloak.representations.idm.ClientRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.Assert; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.page.SessionPortal; -import org.keycloak.testsuite.auth.page.login.Login; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.pages.InfoPage; -import org.keycloak.testsuite.pages.LogoutConfirmPage; -import org.keycloak.testsuite.util.AccountHelper; -import org.keycloak.testsuite.utils.arquillian.ContainerConstants; -import org.keycloak.testsuite.util.SecondBrowser; -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriver; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.*; -import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; -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 SessionServletAdapterTest extends AbstractServletsAdapterTest { - - @Page - private SessionPortal sessionPortalPage; - - @Page - protected LogoutConfirmPage logoutConfirmPage; - - @Page - protected InfoPage infoPage; - - @Override - public void setDefaultPageUriParameters() { - super.setDefaultPageUriParameters(); - oauth.realm(DEMO); - } - - @Deployment(name = SessionPortal.DEPLOYMENT_NAME) - protected static WebArchive sessionPortal() { - return servletDeployment(SessionPortal.DEPLOYMENT_NAME, "keycloak.json", SessionServlet.class); - } - - @After - public void afterSessionServletAdapterTest() { - sessionPortalPage.navigateTo(); - driver.manage().deleteAllCookies(); - } - - @Drone - @SecondBrowser - protected WebDriver driver2; - - //KEYCLOAK-732 - @Test - public void testSingleSessionInvalidated() { - - loginAndCheckSession(testRealmLoginPage); - - // cannot pass to loginAndCheckSession because loginPage is not working together with driver2, therefore copypasta - driver2.navigate().to(sessionPortalPage.toString()); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage, driver2); - driver2.findElement(By.id("username")).sendKeys("bburke@redhat.com"); - driver2.findElement(By.id("password")).sendKeys("password"); - driver2.findElement(By.id("password")).submit(); - assertCurrentUrlEquals(sessionPortalPage, driver2); - String pageSource = driver2.getPageSource(); - MatcherAssert.assertThat(pageSource, containsString("Counter=1")); - // Counter increased now - driver2.navigate().to(sessionPortalPage.toString()); - pageSource = driver2.getPageSource(); - assertTrue(pageSource.contains("Counter=2")); - - // Logout in browser1 - String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) - .build("demo").toString(); - driver.navigate().to(logoutUri); - - logoutConfirmPage.assertCurrent(); - logoutConfirmPage.confirmLogout(); - waitForPageToLoad(); - infoPage.assertCurrent(); - - // Assert that I am logged out in browser1 - sessionPortalPage.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - - // Assert that I am still logged in browser2 and same session is still preserved - driver2.navigate().to(sessionPortalPage.toString()); - assertCurrentUrlEquals(sessionPortalPage, driver2); - pageSource = driver2.getPageSource(); - MatcherAssert.assertThat(pageSource, containsString("Counter=3")); - - // Logout in driver2 - driver2.navigate().to(logoutUri); - driver2.findElement(By.cssSelector("input[type=\"submit\"]")).click(); - Assert.assertEquals("You are logged out", driver2.findElement(By.className("instruction")).getText()); - } - - //KEYCLOAK-741 - @Test - public void testSessionInvalidatedAfterFailedRefresh() { - RealmRepresentation testRealmRep = testRealmResource().toRepresentation(); - ClientResource sessionPortalRes = null; - for (ClientRepresentation clientRep : testRealmResource().clients().findAll()) { - if ("session-portal".equals(clientRep.getClientId())) { - sessionPortalRes = testRealmResource().clients().get(clientRep.getId()); - } - } - assertNotNull(sessionPortalRes); - sessionPortalRes.toRepresentation().setAdminUrl(""); - int origTokenLifespan = testRealmRep.getAccessCodeLifespan(); - testRealmRep.setAccessCodeLifespan(1); - testRealmResource().update(testRealmRep); - - // Login - loginAndCheckSession(testRealmLoginPage); - - // Logout - String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) - .build("demo").toString(); - driver.navigate().to(logoutUri); - logoutConfirmPage.assertCurrent(); - logoutConfirmPage.confirmLogout(); - waitForPageToLoad(); - infoPage.assertCurrent(); - - // Assert that http session was invalidated - sessionPortalPage.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(sessionPortalPage); - String pageSource = driver.getPageSource(); - assertTrue(pageSource.contains("Counter=1")); - - sessionPortalRes.toRepresentation().setAdminUrl(sessionPortalPage.toString()); - testRealmRep.setAccessCodeLifespan(origTokenLifespan); - testRealmResource().update(testRealmRep); - } - - //KEYCLOAK-942 - @Test - public void testAdminApplicationLogout() { - // login as bburke - loginAndCheckSession(testRealmLoginPage); - - // logout mposolda with admin client - UserRepresentation mposolda = testRealmResource().users().search("mposolda", null, null, null, null, null).get(0); - testRealmResource().users().get(mposolda.getId()).logout(); - - // bburke should be still logged with original httpSession in our browser window - sessionPortalPage.navigateTo(); - assertCurrentUrlEquals(sessionPortalPage); - String pageSource = driver.getPageSource(); - assertTrue(pageSource.contains("Counter=3")); - String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) - .build("demo").toString(); - driver.navigate().to(logoutUri); - logoutConfirmPage.assertCurrent(); - logoutConfirmPage.confirmLogout(); - waitForPageToLoad(); - infoPage.assertCurrent(); - } - - //KEYCLOAK-1216 - @Test - public void testAccountManagementSessionsLogout() { - // login as bburke - loginAndCheckSession(testRealmLoginPage); - AccountHelper.logout(testRealmResource(), "bburke@redhat.com"); - // Assert I need to login again (logout was propagated to the app) - loginAndCheckSession(testRealmLoginPage); - } - - private void loginAndCheckSession(Login login) { - sessionPortalPage.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - login.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(sessionPortalPage); - String pageSource = driver.getPageSource(); - assertTrue(pageSource.contains("Counter=1")); - - // Counter increased now - sessionPortalPage.navigateTo(); - pageSource = driver.getPageSource(); - assertTrue(pageSource.contains("Counter=2")); - } - -} - diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/UserStorageConsentTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/UserStorageConsentTest.java deleted file mode 100644 index b7bb2a0fe9..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/UserStorageConsentTest.java +++ /dev/null @@ -1,203 +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.graphene.page.Page; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.common.util.MultivaluedHashMap; -import org.keycloak.models.ClientModel; -import org.keycloak.models.ClientScopeModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ProtocolMapperModel; -import org.keycloak.models.RealmModel; -import org.keycloak.protocol.oidc.OIDCLoginProtocol; -import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; -import org.keycloak.protocol.oidc.OIDCLoginProtocolService; -import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.RoleRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.storage.UserStorageProvider; -import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; -import org.keycloak.testsuite.adapter.page.ProductPortal; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; -import org.keycloak.testsuite.federation.UserMapStorageFactory; -import org.keycloak.testsuite.pages.ConsentPage; -import org.keycloak.testsuite.pages.InfoPage; -import org.keycloak.testsuite.pages.LogoutConfirmPage; -import org.keycloak.testsuite.utils.arquillian.ContainerConstants; - -import jakarta.ws.rs.core.Response; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf; -import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@AppServerContainer(ContainerConstants.APP_SERVER_UNDERTOW) -public class UserStorageConsentTest extends AbstractServletsAdapterTest { - - @Page - private ProductPortal productPortal; - - @Page - protected ConsentPage consentPage; - - @Page - protected LogoutConfirmPage logoutConfirmPage; - - @Page - protected InfoPage infoPage; - - @Deployment(name = ProductPortal.DEPLOYMENT_NAME) - protected static WebArchive productPortal() { - return servletDeployment(ProductPortal.DEPLOYMENT_NAME, ProductServlet.class); - } - - @Before - public void addProvidersBeforeTest() throws URISyntaxException, IOException { - ComponentRepresentation memProvider = new ComponentRepresentation(); - memProvider.setName("memory"); - memProvider.setProviderId(UserMapStorageFactory.PROVIDER_ID); - memProvider.setProviderType(UserStorageProvider.class.getName()); - memProvider.setConfig(new MultivaluedHashMap<>()); - memProvider.getConfig().putSingle("priority", Integer.toString(0)); - memProvider.getConfig().putSingle(IMPORT_ENABLED, Boolean.toString(false)); - - addComponent(memProvider); - } - - protected String addComponent(ComponentRepresentation component) { - Response resp = testRealmResource().components().add(component); - resp.close(); - String id = ApiUtil.getCreatedId(resp); - getCleanup().addComponentId(id); - return id; - } - - public static void setupConsent(KeycloakSession session) { - RealmModel realm = session.realms().getRealmByName("demo"); - ClientModel product = session.clients().getClientByClientId(realm, "product-portal"); - product.setConsentRequired(true); - ClientScopeModel clientScope = realm.addClientScope("clientScope"); - clientScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); - System.err.println("client scope protocol mappers size: " + clientScope.getProtocolMappersStream().count()); - - for (ProtocolMapperModel mapper : product.getProtocolMappersStream().collect(Collectors.toList())) { - if (mapper.getProtocol().equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) { - if (mapper.getName().equals(OIDCLoginProtocolFactory.USERNAME) - || mapper.getName().equals(OIDCLoginProtocolFactory.EMAIL) - || mapper.getName().equals(OIDCLoginProtocolFactory.GIVEN_NAME) - ) { - ProtocolMapperModel copy = new ProtocolMapperModel(); - copy.setName(mapper.getName()); - copy.setProtocol(mapper.getProtocol()); - Map config = new HashMap<>(); - config.putAll(mapper.getConfig()); - copy.setConfig(config); - copy.setProtocolMapper(mapper.getProtocolMapper()); - clientScope.addProtocolMapper(copy); - } - } - product.removeProtocolMapper(mapper); - } - product.addClientScope(clientScope, true); - } - - public static void setupDisplayClientOnConsentScreen(KeycloakSession session) { - RealmModel realm = session.realms().getRealmByName("demo"); - ClientModel product = session.clients().getClientByClientId(realm, "product-portal"); - product.setDisplayOnConsentScreen(true); - } - - /** - * KEYCLOAK-5273 - * - * @throws Exception - */ - @Test - public void testLogin() throws Exception { - assertLogin(); - } - - @Test - public void testLoginDisplayClientOnConsentScreen() throws Exception { - testingClient.server().run(UserStorageConsentTest::setupDisplayClientOnConsentScreen); - assertLogin(); - } - - private void assertLogin() throws InterruptedException { - testingClient.server().run(UserStorageConsentTest::setupConsent); - UserRepresentation memuser = new UserRepresentation(); - memuser.setUsername("memuser"); - String uid = ApiUtil.createUserAndResetPasswordWithAdminClient(testRealmResource(), memuser, "password"); - System.out.println("uid: " + uid); - Assert.assertTrue(uid.startsWith("f:")); // make sure its federated - RoleRepresentation roleRep = adminClient.realm("demo").roles().get("user").toRepresentation(); - List roleList = new ArrayList<>(); - roleList.add(roleRep); - adminClient.realm("demo").users().get(uid).roles().realmLevel().add(roleList); - - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("memuser", "password"); - Assert.assertTrue(consentPage.isCurrent()); - consentPage.confirm(); - assertCurrentUrlEquals(productPortal.toString()); - Assert.assertTrue(driver.getPageSource().contains("iPhone")); - - String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) - .build("demo").toString(); - - driver.navigate().to(logoutUri); - waitForPageToLoad(); - logoutConfirmPage.assertCurrent(); - logoutConfirmPage.confirmLogout(); - waitForPageToLoad(); - infoPage.assertCurrent(); - - driver.navigate().to(productPortal.toString()); - waitForPageToLoad(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - productPortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("memuser", "password"); - assertCurrentUrlEquals(productPortal.toString()); - Assert.assertTrue(driver.getPageSource().contains("iPhone")); - - driver.navigate().to(logoutUri); - waitForPageToLoad(); - logoutConfirmPage.assertCurrent(); - logoutConfirmPage.confirmLogout(); - adminClient.realm("demo").users().delete(uid).close(); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java index 2fa53dd801..d4b64bdc66 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java @@ -82,7 +82,6 @@ import org.junit.Before; import org.junit.Rule; import org.keycloak.OAuth2Constants; import org.keycloak.OAuthErrorException; -import org.keycloak.adapters.AdapterUtils; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator; import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator; @@ -502,7 +501,7 @@ public abstract class AbstractClientPoliciesTest extends AbstractKeycloakTest { private JsonWebToken createRequestToken(String clientId, String realmInfoUrl) { JsonWebToken reqToken = new JsonWebToken(); - reqToken.id(AdapterUtils.generateId()); + reqToken.id(KeycloakModelUtils.generateId()); reqToken.issuer(clientId); reqToken.subject(clientId); reqToken.audience(realmInfoUrl); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java index 388f34ef55..5b9fd62a72 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java @@ -20,8 +20,10 @@ package org.keycloak.testsuite.federation.kerberos; import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; +import jakarta.ws.rs.core.Response; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -33,10 +35,18 @@ import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.security.sasl.Sasl; -import jakarta.ws.rs.core.Response; + import org.apache.http.NameValuePair; +import org.apache.http.auth.AuthSchemeProvider; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.HttpClient; +import org.apache.http.client.config.AuthSchemes; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.HttpClientBuilder; import org.ietf.jgss.GSSCredential; import org.jboss.arquillian.graphene.page.Page; import org.jboss.resteasy.client.jaxrs.ResteasyClient; @@ -44,9 +54,10 @@ import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; + import org.keycloak.OAuth2Constants; -import org.keycloak.adapters.HttpClientBuilder; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.authentication.authenticators.browser.SpnegoAuthenticatorFactory; import org.keycloak.common.constants.KerberosConstants; @@ -74,7 +85,6 @@ import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.util.KerberosRule; import org.keycloak.testsuite.util.KerberosUtils; import org.keycloak.testsuite.util.OAuthClient; -import org.junit.BeforeClass; /** * Contains just helper methods. No test methods. @@ -255,11 +265,18 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest { cleanupApacheHttpClient(); } - HttpClient httpClient = new HttpClientBuilder() - .disableCookieCache(false) - .spNegoSchemeFactory(spnegoSchemeFactory) - .useSPNego(useSpnego) - .build(); + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + if (useSpnego) { + BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("none", "none")); + + httpClientBuilder.setDefaultAuthSchemeRegistry(RegistryBuilder.create() + .register(AuthSchemes.SPNEGO, spnegoSchemeFactory).build()) + .setDefaultRequestConfig(RequestConfig.copy(RequestConfig.DEFAULT) + .setTargetPreferredAuthSchemes(Collections.singletonList(AuthSchemes.SPNEGO)).build()) + .setDefaultCredentialsProvider(credentialsProvider); + } + HttpClient httpClient = httpClientBuilder.build(); ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java index dab918b7e8..8a9c321457 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/LoginPageTest.java @@ -18,6 +18,7 @@ package org.keycloak.testsuite.i18n; import jakarta.ws.rs.core.Response; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; import org.jboss.arquillian.graphene.page.Page; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; @@ -26,7 +27,6 @@ import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.adapters.HttpClientBuilder; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.cookie.CookieType; @@ -146,7 +146,7 @@ public class LoginPageTest extends AbstractI18NTest { @Test public void acceptLanguageHeader() throws IOException { - try(CloseableHttpClient httpClient = (CloseableHttpClient) new HttpClientBuilder().build()) { + try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); ResteasyClient client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java index 8d21eaa075..f42543e592 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java @@ -68,7 +68,6 @@ import org.junit.Rule; import org.junit.rules.TemporaryFolder; import org.keycloak.OAuth2Constants; import org.keycloak.OAuthErrorException; -import org.keycloak.adapters.AdapterUtils; import org.keycloak.admin.client.resource.ClientAttributeCertificateResource; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator; @@ -800,7 +799,7 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe @Override protected JsonWebToken createRequestToken(String clientId, String realmInfoUrl) { JsonWebToken reqToken = new JsonWebToken(); - if (isClaimEnabled("id")) reqToken.id(AdapterUtils.generateId()); + if (isClaimEnabled("id")) reqToken.id(KeycloakModelUtils.generateId()); if (isClaimEnabled("issuer")) reqToken.issuer(clientId); if (isClaimEnabled("subject")) reqToken.subject(clientId); if (isClaimEnabled("audience")) reqToken.audience(realmInfoUrl); @@ -928,7 +927,7 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe protected JsonWebToken createRequestToken(String clientId, String realmInfoUrl) { JsonWebToken reqToken = new JsonWebToken(); - reqToken.id(AdapterUtils.generateId()); + reqToken.id(KeycloakModelUtils.generateId()); reqToken.issuer(clientId); reqToken.subject(clientId); reqToken.audience(realmInfoUrl); diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/keycloak-relative.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/keycloak-relative.json deleted file mode 100644 index 8b97e3c548..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/keycloak-relative.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "demo", - "resource" : "basic-auth-service", - "auth-server-url": "/auth", - "ssl-required" : "external", - "enable-basic-auth" : "true", - "credentials": { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/keycloak.json deleted file mode 100644 index 8b97e3c548..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "demo", - "resource" : "basic-auth-service", - "auth-server-url": "/auth", - "ssl-required" : "external", - "enable-basic-auth" : "true", - "credentials": { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/web.xml deleted file mode 100644 index 0ea56f483f..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/basic-auth/WEB-INF/web.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - basic-auth - - - - /* - - - - user - - - - - KEYCLOAK - demo - - - - user - - \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/keycloak.json deleted file mode 100644 index 64c315749b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "child", - "resource" : "client-linking", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "min-time-between-jwks-requests" : 0, - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/web.xml deleted file mode 100644 index 81425886b6..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/WEB-INF/web.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - client-linking - - - Servlet - org.keycloak.testsuite.adapter.servlet.ClientInitiatedAccountLinkServlet - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - child - - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/childrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/childrealm.json deleted file mode 100644 index e7e9b5d082..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-linking/childrealm.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "id": "child", - "realm": "child", - "enabled": true, - "accessTokenLifespan": 600, - "accessCodeLifespan": 10, - "accessCodeLifespanUserAction": 6000, - "sslRequired": "external", - "registrationAllowed": false, - "requiredCredentials": [ "password" ], - "users" : [ - { - "username" : "bburke@redhat.com", - "enabled": true, - "email" : "bburke@redhat.com", - "firstName": "Bill", - "lastName": "Burke", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - } - ], - "clients": [ - { - "clientId": "client-linking", - "enabled": true, - "adminUrl": "/client-linking", - "baseUrl": "/client-linking", - "redirectUris": [ - "/client-linking/*" - ], - "secret": "password" - } - ] -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal-valid-alg/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal-valid-alg/WEB-INF/keycloak.json deleted file mode 100644 index 30d7614de3..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal-valid-alg/WEB-INF/keycloak.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "realm": "demo", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", - "resource": "client-secret-jwt-secure-portal-valid-alg", - "credentials": { - "secret-jwt": { - "secret": "234234-234234-234234", - "algorithm": "HS512" - } - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal-valid-alg/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal-valid-alg/WEB-INF/web.xml deleted file mode 100644 index a4f2a85b8c..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal-valid-alg/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - client-secret-jwt-secure-portal-valid-alg - - - Servlet - org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet - - - - Servlet - /* - - - - - Permit all - /* - - - * - - - - - KEYCLOAK - demo - - - - admin - - - user - - \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal/WEB-INF/keycloak.json deleted file mode 100644 index 5e755d77b5..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "realm": "demo", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", - "resource": "client-secret-jwt-secure-portal", - "credentials": { - "secret-jwt": { - "secret": "234234-234234-234234" - } - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal/WEB-INF/web.xml deleted file mode 100644 index 25bbef9376..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/client-secret-jwt-secure-portal/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - client-secret-jwt-secure-portal - - - Servlet - org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet - - - - Servlet - /* - - - - - Permit all - /* - - - * - - - - - KEYCLOAK - demo - - - - admin - - - user - - \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal-root/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal-root/WEB-INF/keycloak.json deleted file mode 100644 index 9928e6a175..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal-root/WEB-INF/keycloak.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "realm": "demo", - "resource": "customer-cookie-portal-root", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "expose-token": true, - "token-store": "cookie", - "adapter-state-cookie-path": "/", - "credentials": { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal-root/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal-root/WEB-INF/web.xml deleted file mode 100644 index 955cb1ff74..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal-root/WEB-INF/web.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerServlet - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - AdapterActionsFilter - /* - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - Unsecured - /unsecured/* - - - - - - KEYCLOAK - demo - - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal/WEB-INF/keycloak.json deleted file mode 100644 index 8e19324473..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "realm": "demo", - "resource": "customer-cookie-portal", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "expose-token": true, - "token-store": "cookie", - "credentials": { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal/WEB-INF/web.xml deleted file mode 100644 index 4b7847e8fa..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-cookie-portal/WEB-INF/web.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - customer-cookie-portal - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerServlet - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - AdapterActionsFilter - /* - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - Unsecured - /unsecured/* - - - - - - KEYCLOAK - demo - - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-audience-required/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-audience-required/WEB-INF/keycloak.json deleted file mode 100644 index 34c531021c..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-audience-required/WEB-INF/keycloak.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "realm" : "demo", - "resource" : "customer-db-audience-required", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "bearer-only" : true, - "enable-cors" : true, - "public-key-cache-ttl": 600, - "verify-token-audience": true - -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-audience-required/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-audience-required/WEB-INF/web.xml deleted file mode 100644 index a3b859b878..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-audience-required/WEB-INF/web.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - customer-db-audience-required - - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet - - - - AdapterActionsFilter - /* - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - Unsecured - /unsecured/* - - - - - KEYCLOAK - demo - - - - admin - - - user - - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/keycloak.json deleted file mode 100644 index d1b610c7a3..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "demo", - "resource" : "customer-db", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "bearer-only" : true, - "enable-cors" : true - -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml deleted file mode 100644 index 02136ea14a..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db-error-page/WEB-INF/web.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - customer-db-error-page - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - 400 - /error.html - - - 401 - /error.html - - - 403 - /error.html - - - 500 - /error.html - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - KEYCLOAK - demo - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak-relative.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak-relative.json deleted file mode 100644 index c457468ace..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak-relative.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "demo", - "resource" : "customer-db", - "auth-server-url": "/auth", - "ssl-required" : "external", - "bearer-only" : true, - "enable-cors" : true - -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json deleted file mode 100644 index 400fac3871..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "demo", - "resource" : "customer-db", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "bearer-only" : true, - "enable-cors" : true, - "public-key-cache-ttl": 600 - -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml deleted file mode 100644 index 56ed0e725a..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - customer-db - - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet - - - - AdapterActionsFilter - /* - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - Unsecured - /unsecured/* - - - - - KEYCLOAK - demo - - - - admin - - - user - - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal-noconf/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal-noconf/WEB-INF/web.xml deleted file mode 100644 index 71fd5cdb32..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal-noconf/WEB-INF/web.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - customer-portal-noconf - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerServletNoConf - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - KEYCLOAK - demo - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal-subsystem/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal-subsystem/WEB-INF/web.xml deleted file mode 100644 index 280c9e96f0..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal-subsystem/WEB-INF/web.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - customer-portal-subsystem - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerServlet - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - KEYCLOAK - demo - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/keycloak-relative.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/keycloak-relative.json deleted file mode 100644 index a796d1a2fc..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/keycloak-relative.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm": "demo", - "resource": "customer-portal", - "auth-server-url": "/auth", - "ssl-required" : "external", - "credentials": { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/keycloak.json deleted file mode 100644 index e6e9c427db..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "realm": "demo", - "resource": "customer-portal", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "expose-token": true, - "min-time-between-jwks-requests": 120, - "credentials": { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/web.xml deleted file mode 100644 index 50e3c38fe4..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-portal/WEB-INF/web.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - customer-portal - - - Servlet - org.keycloak.testsuite.adapter.servlet.CustomerServlet - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - KEYCLOAK - demo - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/WEB-INF/keycloak.json deleted file mode 100644 index 7b41211c17..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "child", - "resource" : "exchange-linking", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "min-time-between-jwks-requests" : 0, - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/WEB-INF/web.xml deleted file mode 100644 index 4e87ad2597..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/WEB-INF/web.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - exchange-linking - - - Servlet - org.keycloak.testsuite.adapter.servlet.LinkAndExchangeServlet - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - child - - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/childrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/childrealm.json deleted file mode 100644 index 40ad4e414f..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/exchange-linking/childrealm.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "id": "child", - "realm": "child", - "enabled": true, - "accessTokenLifespan": 600, - "accessCodeLifespan": 10, - "accessCodeLifespanUserAction": 6000, - "sslRequired": "external", - "registrationAllowed": false, - "requiredCredentials": [ "password" ], - "users" : [ - { - "username" : "bburke@redhat.com", - "enabled": true, - "email" : "bburke@redhat.com", - "firstName": "Bill", - "lastName": "Burke", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - } - ], - "clients": [ - { - "clientId": "exchange-linking", - "enabled": true, - "adminUrl": "/exchange-linking", - "baseUrl": "/exchange-linking", - "redirectUris": [ - "/exchange-linking/*" - ], - "secret": "password" - } - ] -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json deleted file mode 100644 index 0a72fd5c68..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/input-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "demo", - "resource" : "input-portal", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "min-time-between-jwks-requests": 120, - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml deleted file mode 100644 index 0ce1561ccc..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/input-portal/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - input-portal - - - Servlet - org.keycloak.testsuite.adapter.servlet.InputServlet - - - - Servlet - /* - - - - - Users - /secured/* - - - user - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/tenant1-keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/tenant1-keycloak.json deleted file mode 100644 index 76432861b4..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/tenant1-keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "tenant1", - "resource" : "multi-tenant", - "realm-public-key" : "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3wAQl0VcOVlT7JIttt0cVpksLDjASjfI9zl0c7U5eMWAt0SCOT1EIMjPjtrjO8eyudi7ckwP3NcEHL3QKoNEzwxHpccW7Y2RwVfsFHXkSRvWaxFtxHGNd1NRF4RNMGsCdtCyaybhknItTnOWjRy4jsgHmxDN8rwOWCF0RfnNwXWGefUcF1fe5vpNj+1u2diIUgaR9GC4zpzaDNT68fhzSt92F6ZaU4/niRdfBOoBxHW25HSqqsDKS/xMhlBB19UFUsKTraPsJjQTEpi0vqdpx88a2NjzKRaShHa/p08SyY5cZtgU99TjW7+uvWD0ka4Wf+BziyJSU0xCyFxek5z95QIDAQAB", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/tenant2-keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/tenant2-keycloak.json deleted file mode 100644 index aa29cbac2a..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/tenant2-keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "tenant2", - "resource" : "multi-tenant", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/web.xml deleted file mode 100644 index 644b1f01ce..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/multi-tenant/WEB-INF/web.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - multi-tenant - - - MultiTenantServlet - org.keycloak.testsuite.adapter.servlet.MultiTenantServlet - - - - keycloak.config.resolver - org.keycloak.testsuite.adapter.servlet.MultiTenantResolver - - - - MultiTenantServlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - not-important - - - - user - - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/no-access-token/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/no-access-token/WEB-INF/keycloak.json deleted file mode 100644 index 3d64883cd0..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/no-access-token/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "demo", - "resource" : "no-access-token", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - }, - "ignore-oauth-query-parameter": true -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/no-access-token/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/no-access-token/WEB-INF/web.xml deleted file mode 100644 index 7d8f2ec79f..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/no-access-token/WEB-INF/web.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - no-access-token - - - Servlet - org.keycloak.testsuite.adapter.servlet.InputServlet - - - - Servlet - /* - - - - - Users - /secured/* - - - user - - - - - public - /* - - - - - KEYCLOAK - demo - - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/WEB-INF/keycloak.json deleted file mode 100644 index 80f66e0877..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm": "test", - "resource": "offline-client", - "auth-server-url": "http://localhost:8081/auth", - "ssl-required" : "external", - "credentials": { - "secret": "secret1" - }, - "min-time-between-jwks-requests": 1 -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/WEB-INF/web.xml deleted file mode 100644 index e7a1003de5..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/WEB-INF/web.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - offline-client - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - org.keycloak.testsuite.adapter.servlet.OfflineTokenServlet - - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - AdapterActionsFilter - /* - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Unsecured - /unsecured/* - - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - KEYCLOAK - test - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json deleted file mode 100644 index b7daf0fdff..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json +++ /dev/null @@ -1,214 +0,0 @@ -{ - "id": "test", - "realm": "test", - "enabled": true, - "accessTokenLifespan": 10, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespan": 5184000, - "sslRequired": "external", - "registrationAllowed": true, - "resetPasswordAllowed": true, - "editUsernameAllowed" : true, - "requiredCredentials": [ "password" ], - "defaultRoles": [ "user" ], - "smtpServer": { - "from": "auto@keycloak.org", - "host": "localhost", - "port":"3025" - }, - "users" : [ - { - "username" : "test-user@localhost", - "enabled": true, - "email" : "test-user@localhost", - "firstName": "Tom", - "lastName": "Brady", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "realmRoles": ["user", "offline_access"], - "clientRoles": { - "test-app": [ "customer-user" ], - "account": [ "view-profile", "manage-account" ] - } - }, - { - "username" : "john-doh@localhost", - "enabled": true, - "email" : "john-doh@localhost", - "firstName": "John", - "lastName": "Doh", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "realmRoles": ["user"], - "clientRoles": { - "test-app": [ "customer-user" ], - "account": [ "view-profile", "manage-account" ] - } - }, - { - "username" : "keycloak-user@localhost", - "enabled": true, - "email" : "keycloak-user@localhost", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "realmRoles": ["user"], - "clientRoles": { - "test-app": [ "customer-user" ], - "account": [ "view-profile", "manage-account" ] - } - }, - { - "username" : "topGroupUser", - "enabled": true, - "email" : "top@redhat.com", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "groups": [ - "/topGroup" - ] - }, - { - "username" : "level2GroupUser", - "enabled": true, - "email" : "level2@redhat.com", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "groups": [ - "/topGroup/level2group" - ] - } - ], - "scopeMappings": [ - { - "client": "third-party", - "roles": ["user"] - }, - { - "client": "test-app", - "roles": ["user"] - }, - { - "client": "offline-client", - "roles": ["user","offline_access"] - } - ], - "clients": [ - { - "clientId": "test-app", - "enabled": true, - "baseUrl": "http://localhost:8180/auth/realms/master/app", - "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" - ], - "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", - "secret": "password", - "attributes" : { - "exclude.issuer.from.auth.response": "true" - } - }, - { - "clientId" : "third-party", - "enabled": true, - "consentRequired": true, - - "redirectUris": [ - "http://localhost:8180/app/*" - ], - "secret": "password", - "attributes" : { - "exclude.issuer.from.auth.response": "true" - } - }, - { - "clientId": "offline-client", - "enabled": true, - "adminUrl": "/offline-client/logout", - "baseUrl": "/offline-client", - "directAccessGrantsEnabled": true, - "redirectUris": [ - "/offline-client/*" - ], - "secret": "secret1", - "attributes" : { - "exclude.issuer.from.auth.response": "true" - } - } - - ], - "roles" : { - "realm" : [ - { - "name": "user", - "description": "Have User privileges" - }, - { - "name": "admin", - "description": "Have Administrator privileges" - } - ], - "client" : { - "test-app" : [ - { - "name": "customer-user", - "description": "Have Customer User privileges" - }, - { - "name": "customer-admin", - "description": "Have Customer Admin privileges" - } - ] - } - - }, - "groups" : [ - { - "name": "topGroup", - "attributes": { - "topAttribute": ["true"] - - }, - "realmRoles": ["user"], - - "subGroups": [ - { - "name": "level2group", - "realmRoles": ["admin"], - "clientRoles": { - "test-app": ["customer-user"] - }, - "attributes": { - "level2Attribute": ["true"] - - } - } - ] - } - ], - - - "clientScopeMappings": { - "test-app": [ - { - "client": "third-party", - "roles": ["customer-user"] - } - ] - }, - - "internationalizationEnabled": true, - "supportedLocales": ["en", "de"], - "defaultLocale": "en", - "eventsListeners": ["jboss-logging", "event-queue"] -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal-autodetect-bearer-only/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal-autodetect-bearer-only/WEB-INF/keycloak.json deleted file mode 100644 index ca2ef18669..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal-autodetect-bearer-only/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm" : "demo", - "resource" : "product-portal-autodetect-bearer-only", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - }, - "autodetect-bearer-only" : true -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal-autodetect-bearer-only/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal-autodetect-bearer-only/WEB-INF/web.xml deleted file mode 100644 index 0f41c306f8..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal-autodetect-bearer-only/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - product-portal-autodetect-bearer-only - - - Servlet - org.keycloak.testsuite.adapter.servlet.ProductServlet - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/keycloak-relative.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/keycloak-relative.json deleted file mode 100644 index 9ef62ff67a..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/keycloak-relative.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "demo", - "resource" : "product-portal", - "auth-server-url" : "/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/keycloak.json deleted file mode 100644 index 4754e2b9bf..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "demo", - "resource" : "product-portal", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/web.xml deleted file mode 100644 index 8f184a56de..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/product-portal/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - product-portal - - - Servlet - org.keycloak.testsuite.adapter.servlet.ProductServlet - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/keycloak.json deleted file mode 100644 index 443a08cfdf..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/keycloak.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "realm": "demo", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", - "resource": "secure-portal-with-custom-session-config", - "credentials": { - "jwt": { - "client-key-password": "password", - "client-keystore-file": "classpath:keystore.jks", - "client-keystore-password": "password", - "client-key-alias": "secure-portal", - "token-timeout": 10, - "client-keystore-type": "jks" - } - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/keystore.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/keystore.jks deleted file mode 100644 index 399be7a48a..0000000000 Binary files a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/keystore.jks and /dev/null differ diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/web.xml deleted file mode 100644 index bfcc1db59b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-custom-session-config/WEB-INF/web.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - secure-portal-with-custom-session-config - - - Servlet - org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet - - - - Servlet - /* - - - - - Permit all - /* - - - * - - - - - - true - CUSTOM_JSESSION_ID_NAME - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/keycloak.json deleted file mode 100644 index e3cd38585b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/keycloak.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "realm": "demo", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", - "resource": "secure-portal-with-rewrite-redirect-uri", - "credentials": { - "jwt": { - "client-key-password": "password", - "client-keystore-file": "classpath:keystore.jks", - "client-keystore-password": "password", - "client-key-alias": "secure-portal", - "token-timeout": 10, - "client-keystore-type": "jks" - } - }, - "redirect-rewrite-rules": { - "^/(.*)$" : "/rewritten" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/keystore.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/keystore.jks deleted file mode 100644 index 399be7a48a..0000000000 Binary files a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/keystore.jks and /dev/null differ diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/web.xml deleted file mode 100644 index 5ab42538b9..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal-with-rewrite-redirect-uri/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - secure-portal-with-rewrite-redirect-uri - - - Servlet - org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet - - - - Servlet - /* - - - - - Permit all - /* - - - * - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json deleted file mode 100644 index f3fa1a59f0..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "realm": "demo", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", - "resource": "secure-portal", - "credentials": { - "jwt": { - "client-key-password": "password", - "client-keystore-file": "classpath:keystore.jks", - "client-keystore-password": "password", - "client-key-alias": "secure-portal", - "token-timeout": 10, - "client-keystore-type": "jks" - } - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keystore.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keystore.jks deleted file mode 100644 index 399be7a48a..0000000000 Binary files a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keystore.jks and /dev/null differ diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/web.xml deleted file mode 100644 index ace743619b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/web.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - secure-portal - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet - - - - AdapterActionsFilter - /* - - - - Servlet - /* - - - - - Permit all - /* - - - * - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/serialization-servlet/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/serialization-servlet/WEB-INF/keycloak.json deleted file mode 100644 index d861ea9e66..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/serialization-servlet/WEB-INF/keycloak.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "realm": "demo", - "resource": "serialization-servlet", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "expose-token": true, - "credentials": { - "secret": "password" - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/serialization-servlet/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/serialization-servlet/WEB-INF/web.xml deleted file mode 100644 index e9b6913cf3..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/serialization-servlet/WEB-INF/web.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - serialization-servlet - - - Servlet - org.keycloak.testsuite.adapter.servlet.SerializationServlet - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - KEYCLOAK - demo - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal-distributable/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal-distributable/WEB-INF/keycloak.json deleted file mode 100644 index dd572300e7..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal-distributable/WEB-INF/keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "demo", - "resource" : "session-portal-distributable", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal-distributable/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal-distributable/WEB-INF/web.xml deleted file mode 100644 index 8fbba243ac..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal-distributable/WEB-INF/web.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - session-portal-distributable - - - - - - - Servlet - org.keycloak.testsuite.adapter.servlet.SessionServlet - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal/WEB-INF/keycloak.json deleted file mode 100644 index 6dd476f05b..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal/WEB-INF/keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm" : "demo", - "resource" : "session-portal", - "auth-server-url" : "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials" : { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal/WEB-INF/web.xml deleted file mode 100644 index 2f0dbb2236..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/session-portal/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - session-portal - - - Servlet - org.keycloak.testsuite.adapter.servlet.SessionServlet - - - - Servlet - /* - - - - - Users - /* - - - user - - - - - KEYCLOAK - demo - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json deleted file mode 100644 index b57ad5a80a..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "id": "tenant1", - "realm": "tenant1", - "enabled": true, - "accessTokenLifespan": 3000, - "accessCodeLifespan": 10, - "accessCodeLifespanUserAction": 6000, - "sslRequired": "external", - "registrationAllowed": false, - "privateKey": "MIIEpQIBAAKCAQEA3wAQl0VcOVlT7JIttt0cVpksLDjASjfI9zl0c7U5eMWAt0SCOT1EIMjPjtrjO8eyudi7ckwP3NcEHL3QKoNEzwxHpccW7Y2RwVfsFHXkSRvWaxFtxHGNd1NRF4RNMGsCdtCyaybhknItTnOWjRy4jsgHmxDN8rwOWCF0RfnNwXWGefUcF1fe5vpNj+1u2diIUgaR9GC4zpzaDNT68fhzSt92F6ZaU4/niRdfBOoBxHW25HSqqsDKS/xMhlBB19UFUsKTraPsJjQTEpi0vqdpx88a2NjzKRaShHa/p08SyY5cZtgU99TjW7+uvWD0ka4Wf+BziyJSU0xCyFxek5z95QIDAQABAoIBABDt66na8CdtFVFOalNe8eR5IxYFsO4cJ2ZCtwkvEY/jno6gkCpRm7cex53BbE2A2ZwA939ehY3EcmF5ijDQCmHq6BLjzGUjFupQscbT3w2AeYS4rAFP2ueGLGUr/BgtkjWm869CzQ6AcIQWLlsZemwMhNdMLUu85HHjCEq6WNko3fnZ3z0vigSeV7u5LpYVlSQ6dQnjBU51iL7lmeTRZjzIQ8RSpuwi/7K+JKeHFaUSatb40lQRSnAa/ZJgtIKgmVl21wPuCmQALSB/orY6jMuXFpyAOZE3CuNQr18E3o3hPyPiuAR9vq4DYQbRE0QmsLe/eFpl2lxay+EDb9KcxnkCgYEA9QcldhmzqKJMNOw8s/dwUIiJEWTpbi3WyMtY9vIDbBjVmeuX1YerBRfX3KhaHovgcw4Boc6LQ7Kuz7J/1OJ0PvMwF3y17ufq6V3WAXbzivTSCRgd1/53waPdrYiRAeAhTWVjL+8FvUbT1YlWSMYbXTdK8LZWm0WTMcNb9xuwIPMCgYEA6PxoETNRuJNaAKiVNBQr4p+goaUKC4m/a1iwff4Sk7B8eI/AsNWsowe9157QUOmdiVTwuIvkX8ymEsvgQxM7l5TVly6TuQNtf/oDMgj3h+23Wy50v4ErLTxYTnk4YGvAbhGEeRcxtVd3GP74avgID/pUiWyS8Ii052LR6l1PW8cCgYEAz987McFGQKdHvZI5QXiHKVtb5YzV2Go9EGYrWH0i2B8Nf6J2UmnhddWvhPyyT73dMd7NFaezUECTu5K0jjd75TfNMe/ULRVFnqvD9cQjg1yFn798+hRhJr9NPn5gftXViuKbzjuag+RFrJ/xupWO+3sAMcyPFvVkldAmAjLULm8CgYEAkDacW/k+HlfnH/05zbCmsXJJRYUYwKeU+uc859/6s7xMb3vbtBmu8IL8OZkuLMdOIhGXp0PAKqRML9pOiHZBLsSLqTbFbYH3p32juLbgMR0tn50T2u4jQa7WokxaXySTSg5Bx4pZ1Hu9VpWMQvogU3OKHD4+ffDAuXDrqnvzgUUCgYEAvoWI1az7E/LP59Fg6xPDSDnbl9PlQvHY8G7ppJXYzSvVWlk7Wm1VoTA4wFonD24okJ8jgRw6EBTRkM0Y8dg2dKvynJw3oUJdhmHL4mnb6bOhMbFU03cg9cm/YR1Vb/1eJXqrFYdnrMXx9T9udUT6OAKCkER+/uRv8gARRSzOYIE=", - "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3wAQl0VcOVlT7JIttt0cVpksLDjASjfI9zl0c7U5eMWAt0SCOT1EIMjPjtrjO8eyudi7ckwP3NcEHL3QKoNEzwxHpccW7Y2RwVfsFHXkSRvWaxFtxHGNd1NRF4RNMGsCdtCyaybhknItTnOWjRy4jsgHmxDN8rwOWCF0RfnNwXWGefUcF1fe5vpNj+1u2diIUgaR9GC4zpzaDNT68fhzSt92F6ZaU4/niRdfBOoBxHW25HSqqsDKS/xMhlBB19UFUsKTraPsJjQTEpi0vqdpx88a2NjzKRaShHa/p08SyY5cZtgU99TjW7+uvWD0ka4Wf+BziyJSU0xCyFxek5z95QIDAQAB", - "requiredCredentials": [ "password" ], - "users" : [ - { - "username" : "bburke@redhat.com", - "enabled": true, - "email" : "bburke@redhat.com", - "firstName": "Bill", - "lastName": "Burke", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "realmRoles": [ "user" ], - "clientRoles": { - "multi-tenant": [ "user" ] - } - }, - { - "username" : "user-tenant1", - "enabled": true, - "email" : "user-tenant1@redhat.com", - "firstName": "Bill", - "lastName": "Burke", - "credentials" : [ - { "type" : "password", - "value" : "user-tenant1" } - ], - "realmRoles": [ "user" ], - "clientRoles": { - "multi-tenant": [ "user" ] - } - } - ], - "roles" : { - "realm" : [ - { - "name": "user", - "description": "User privileges" - } - ] - }, - "scopeMappings": [ - { - "client": "multi-tenant", - "roles": ["user"] - } - - ], - "clients": [ - { - "clientId": "multi-tenant", - "enabled": true, - "adminUrl": "/multi-tenant/tenant1", - "baseUrl": "/multi-tenant/tenant1", - "redirectUris": [ - "/multi-tenant/tenant1/*" - ], - "secret": "password", - "attributes" : { - "exclude.issuer.from.auth.response": "true" - } - } - ] -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json deleted file mode 100644 index 14981d901f..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "id": "tenant2", - "realm": "tenant2", - "enabled": true, - "accessTokenLifespan": 3000, - "accessCodeLifespan": 10, - "accessCodeLifespanUserAction": 6000, - "sslRequired": "external", - "registrationAllowed": false, - "requiredCredentials": [ "password" ], - "users" : [ - { - "username" : "bburke@redhat.com", - "enabled": true, - "email" : "bburke@redhat.com", - "firstName": "Bill", - "lastName": "Burke", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ], - "realmRoles": [ "user" ], - "clientRoles": { - "multi-tenant": [ "user" ] - } - }, - { - "username" : "user-tenant2", - "enabled": true, - "email" : "user-tenant2@redhat.com", - "firstName": "Bill", - "lastName": "Burke", - "credentials" : [ - { "type" : "password", - "value" : "user-tenant2" } - ], - "realmRoles": [ "user" ], - "clientRoles": { - "multi-tenant": [ "user" ] - } - } - ], - "roles" : { - "realm" : [ - { - "name": "user", - "description": "User privileges" - } - ] - }, - "scopeMappings": [ - { - "client": "multi-tenant", - "roles": ["user"] - } - - ], - "clients": [ - { - "clientId": "multi-tenant", - "enabled": true, - "adminUrl": "/multi-tenant/tenant2", - "baseUrl": "/multi-tenant/tenant2", - "redirectUris": [ - "/multi-tenant/tenant2/*" - ], - "secret": "password", - "attributes" : { - "exclude.issuer.from.auth.response": "true" - } - } - ] -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-min-ttl/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-min-ttl/WEB-INF/keycloak.json deleted file mode 100644 index b86e018279..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-min-ttl/WEB-INF/keycloak.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "realm": "demo", - "resource": "token-min-ttl", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials": { - "secret": "password" - }, - "token-minimum-time-to-live": 120, - "min-time-between-jwks-requests": 120 -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-min-ttl/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-min-ttl/WEB-INF/web.xml deleted file mode 100644 index 86d07f5ee6..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-min-ttl/WEB-INF/web.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - token-min-ttl - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - org.keycloak.testsuite.adapter.servlet.TokenMinTTLServlet - - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - AdapterActionsFilter - /* - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - Unsecured - /unsecured/* - - - - - KEYCLOAK - test - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-refresh/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-refresh/WEB-INF/keycloak.json deleted file mode 100644 index 8b50173f8f..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-refresh/WEB-INF/keycloak.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "realm": "demo", - "resource": "token-refresh", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required" : "external", - "credentials": { - "secret": "password" - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-refresh/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-refresh/WEB-INF/web.xml deleted file mode 100644 index dbe6ef9850..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/token-refresh/WEB-INF/web.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - token-refresh - - - AdapterActionsFilter - org.keycloak.testsuite.adapter.filter.AdapterActionsFilter - - - - Servlet - org.keycloak.testsuite.adapter.servlet.TokenMinTTLServlet - - - - Error Servlet - org.keycloak.testsuite.adapter.servlet.ErrorServlet - - - - AdapterActionsFilter - /* - - - - Servlet - /* - - - - Error Servlet - /error.html - - - - - Users - /* - - - user - - - - - Errors - /error.html - - - - - Unsecured - /unsecured/* - - - - - KEYCLOAK - test - - /error.html - /error.html - - - - - admin - - - user - - diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java deleted file mode 100644 index 50c57fc2ae..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java +++ /dev/null @@ -1,550 +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.adapters; - -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.jboss.logging.Logger; -import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.adapters.rotation.PublicKeyLocator; -import org.keycloak.adapters.spi.HttpFacade; -import org.keycloak.common.enums.RelativeUrlsUsed; -import org.keycloak.common.enums.SslRequired; -import org.keycloak.common.util.KeycloakUriBuilder; -import org.keycloak.enums.TokenStore; -import org.keycloak.protocol.oidc.client.authentication.ClientCredentialsProvider; -import org.keycloak.representations.adapters.config.AdapterConfig; - -import java.io.IOException; -import java.net.URI; -import java.util.Map; -import java.util.concurrent.Callable; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class AdapterDeploymentContext { - private static final Logger log = Logger.getLogger(AdapterDeploymentContext.class); - protected KeycloakDeployment deployment; - protected KeycloakConfigResolver configResolver; - - public AdapterDeploymentContext() { - } - - /** - * For single-tenant deployments, this constructor is to be used, as a - * full KeycloakDeployment is known at deployment time and won't change - * during the application deployment's life cycle. - * - * @param deployment A KeycloakConfigResolver, possibly missing the Auth - * Server URL - */ - public AdapterDeploymentContext(KeycloakDeployment deployment) { - this.deployment = deployment; - } - - /** - * For multi-tenant deployments, this constructor is to be used, as a - * KeycloakDeployment is not known at deployment time. It defers the - * resolution of a KeycloakDeployment to a KeycloakConfigResolver, - * to be implemented by the target application. - * - * @param configResolver A KeycloakConfigResolver that will be used - * to resolve a KeycloakDeployment - */ - public AdapterDeploymentContext(KeycloakConfigResolver configResolver) { - this.configResolver = configResolver; - } - - /** - * For single-tenant deployments, it complements KeycloakDeployment - * by resolving a relative Auth Server's URL based on the current request - * - * For multi-tenant deployments, defers the resolution of KeycloakDeployment - * to the KeycloakConfigResolver . - * - * @param facade the Request/Response Façade , used to either determine - * the Auth Server URL (single tenant) or pass thru to the - * KeycloakConfigResolver. - * @return - */ - public KeycloakDeployment resolveDeployment(HttpFacade facade) { - if (null != configResolver) { - return configResolver.resolve(facade.getRequest()); - } - - if (deployment == null) return null; - if (deployment.getAuthServerBaseUrl() == null) return deployment; - - KeycloakDeployment resolvedDeployment = resolveUrls(deployment, facade); - if (resolvedDeployment.getPublicKeyLocator() == null) { - throw new RuntimeException("KeycloakDeployment was never initialized through appropriate SPIs"); - } - return resolvedDeployment; - } - - protected KeycloakDeployment resolveUrls(KeycloakDeployment deployment, HttpFacade facade) { - if (deployment.relativeUrls == RelativeUrlsUsed.NEVER) { - // Absolute URI are already set to everything - return deployment; - } else { - DeploymentDelegate delegate = new DeploymentDelegate(this.deployment); - delegate.setAuthServerBaseUrl(getBaseBuilder(facade, this.deployment.getAuthServerBaseUrl()).build().toString()); - return delegate; - } - } - - /** - * This delegate is used to store temporary, per-request metadata like request resolved URLs. - * Ever method is delegated except URL get methods and isConfigured() - * - */ - protected static class DeploymentDelegate extends KeycloakDeployment { - protected KeycloakDeployment delegate; - - public DeploymentDelegate(KeycloakDeployment delegate) { - this.delegate = delegate; - } - - public void setAuthServerBaseUrl(String authServerBaseUrl) { - this.authServerBaseUrl = authServerBaseUrl; - KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl); - resolveUrls(serverBuilder); - } - - @Override - public RelativeUrlsUsed getRelativeUrls() { - return delegate.getRelativeUrls(); - } - - @Override - public String getRealmInfoUrl() { - return (this.realmInfoUrl != null) ? this.realmInfoUrl : delegate.getRealmInfoUrl(); - } - - @Override - public String getTokenUrl() { - return (this.tokenUrl != null) ? this.tokenUrl : delegate.getTokenUrl(); - } - - @Override - public KeycloakUriBuilder getLogoutUrl() { - return (this.logoutUrl != null) ? this.logoutUrl : delegate.getLogoutUrl(); - } - - @Override - public String getAccountUrl() { - return (this.accountUrl != null) ? this.accountUrl : delegate.getAccountUrl(); - } - - @Override - public String getRegisterNodeUrl() { - return (this.registerNodeUrl != null) ? this.registerNodeUrl : delegate.getRegisterNodeUrl(); - } - - @Override - public String getUnregisterNodeUrl() { - return (this.unregisterNodeUrl != null) ? this.unregisterNodeUrl : delegate.getUnregisterNodeUrl(); - } - - @Override - public String getJwksUrl() { - return (this.jwksUrl != null) ? this.jwksUrl : delegate.getJwksUrl(); - } - - @Override - public String getResourceName() { - return delegate.getResourceName(); - } - - @Override - public String getRealm() { - return delegate.getRealm(); - } - - @Override - public void setRealm(String realm) { - delegate.setRealm(realm); - } - - @Override - public void setPublicKeyLocator(PublicKeyLocator publicKeyLocator) { - delegate.setPublicKeyLocator(publicKeyLocator); - } - - @Override - public PublicKeyLocator getPublicKeyLocator() { - return delegate.getPublicKeyLocator(); - } - - @Override - public void setResourceName(String resourceName) { - delegate.setResourceName(resourceName); - } - - @Override - public boolean isBearerOnly() { - return delegate.isBearerOnly(); - } - - @Override - public void setBearerOnly(boolean bearerOnly) { - delegate.setBearerOnly(bearerOnly); - } - - @Override - public boolean isAutodetectBearerOnly() { - return delegate.isAutodetectBearerOnly(); - } - - @Override - public void setAutodetectBearerOnly(boolean autodetectBearerOnly) { - delegate.setAutodetectBearerOnly(autodetectBearerOnly); - } - - @Override - public boolean isEnableBasicAuth() { - return delegate.isEnableBasicAuth(); - } - - @Override - public void setEnableBasicAuth(boolean enableBasicAuth) { - delegate.setEnableBasicAuth(enableBasicAuth); - } - - @Override - public boolean isPublicClient() { - return delegate.isPublicClient(); - } - - @Override - public void setPublicClient(boolean publicClient) { - delegate.setPublicClient(publicClient); - } - - @Override - public Map getResourceCredentials() { - return delegate.getResourceCredentials(); - } - - @Override - public void setResourceCredentials(Map resourceCredentials) { - delegate.setResourceCredentials(resourceCredentials); - } - - @Override - public void setClientAuthenticator(ClientCredentialsProvider clientAuthenticator) { - delegate.setClientAuthenticator(clientAuthenticator); - } - - @Override - public ClientCredentialsProvider getClientAuthenticator() { - return delegate.getClientAuthenticator(); - } - - @Override - public HttpClient getClient() { - return delegate.getClient(); - } - - @Override - public void setClient(HttpClient client) { - delegate.setClient(client); - } - - @Override - public String getScope() { - return delegate.getScope(); - } - - @Override - public void setScope(String scope) { - delegate.setScope(scope); - } - - @Override - public SslRequired getSslRequired() { - return delegate.getSslRequired(); - } - - @Override - public void setSslRequired(SslRequired sslRequired) { - delegate.setSslRequired(sslRequired); - } - - @Override - public int getConfidentialPort() { - return delegate.getConfidentialPort(); - } - - @Override - public void setConfidentialPort(int confidentialPort) { - delegate.setConfidentialPort(confidentialPort); - } - - @Override - public TokenStore getTokenStore() { - return delegate.getTokenStore(); - } - - @Override - public void setTokenStore(TokenStore tokenStore) { - delegate.setTokenStore(tokenStore); - } - - @Override - public String getAdapterStateCookiePath() { - return delegate.getAdapterStateCookiePath(); - } - - @Override - public void setAdapterStateCookiePath(String adapterStateCookiePath) { - delegate.setAdapterStateCookiePath(adapterStateCookiePath); - } - - @Override - public String getStateCookieName() { - return delegate.getStateCookieName(); - } - - @Override - public void setStateCookieName(String stateCookieName) { - delegate.setStateCookieName(stateCookieName); - } - - @Override - public boolean isUseResourceRoleMappings() { - return delegate.isUseResourceRoleMappings(); - } - - @Override - public void setUseResourceRoleMappings(boolean useResourceRoleMappings) { - delegate.setUseResourceRoleMappings(useResourceRoleMappings); - } - - @Override - public boolean isCors() { - return delegate.isCors(); - } - - @Override - public void setCors(boolean cors) { - delegate.setCors(cors); - } - - @Override - public int getCorsMaxAge() { - return delegate.getCorsMaxAge(); - } - - @Override - public void setCorsMaxAge(int corsMaxAge) { - delegate.setCorsMaxAge(corsMaxAge); - } - - @Override - public String getCorsAllowedHeaders() { - return delegate.getCorsAllowedHeaders(); - } - - @Override - public void setNotBefore(int notBefore) { - delegate.setNotBefore(notBefore); - } - - @Override - public int getNotBefore() { - return delegate.getNotBefore(); - } - - @Override - public void updateNotBefore(int notBefore) { - delegate.setNotBefore(notBefore); - getPublicKeyLocator().reset(this); - } - - @Override - public void setExposeToken(boolean exposeToken) { - delegate.setExposeToken(exposeToken); - } - - @Override - public boolean isExposeToken() { - return delegate.isExposeToken(); - } - - @Override - public void setCorsAllowedMethods(String corsAllowedMethods) { - delegate.setCorsAllowedMethods(corsAllowedMethods); - } - - @Override - public String getCorsAllowedMethods() { - return delegate.getCorsAllowedMethods(); - } - - @Override - public void setCorsAllowedHeaders(String corsAllowedHeaders) { - delegate.setCorsAllowedHeaders(corsAllowedHeaders); - } - - @Override - public boolean isAlwaysRefreshToken() { - return delegate.isAlwaysRefreshToken(); - } - - @Override - public void setAlwaysRefreshToken(boolean alwaysRefreshToken) { - delegate.setAlwaysRefreshToken(alwaysRefreshToken); - } - - @Override - public int getRegisterNodePeriod() { - return delegate.getRegisterNodePeriod(); - } - - @Override - public void setRegisterNodePeriod(int registerNodePeriod) { - delegate.setRegisterNodePeriod(registerNodePeriod); - } - - @Override - public void setRegisterNodeAtStartup(boolean registerNodeAtStartup) { - delegate.setRegisterNodeAtStartup(registerNodeAtStartup); - } - - @Override - public boolean isRegisterNodeAtStartup() { - return delegate.isRegisterNodeAtStartup(); - } - - @Override - public String getPrincipalAttribute() { - return delegate.getPrincipalAttribute(); - } - - @Override - public void setPrincipalAttribute(String principalAttribute) { - delegate.setPrincipalAttribute(principalAttribute); - } - - @Override - public boolean isTurnOffChangeSessionIdOnLogin() { - return delegate.isTurnOffChangeSessionIdOnLogin(); - } - - @Override - public void setTurnOffChangeSessionIdOnLogin(boolean turnOffChangeSessionIdOnLogin) { - delegate.setTurnOffChangeSessionIdOnLogin(turnOffChangeSessionIdOnLogin); - } - - @Override - public int getTokenMinimumTimeToLive() { - return delegate.getTokenMinimumTimeToLive(); - } - - @Override - public void setTokenMinimumTimeToLive(final int tokenMinimumTimeToLive) { - delegate.setTokenMinimumTimeToLive(tokenMinimumTimeToLive); - } - - @Override - public PolicyEnforcer getPolicyEnforcer() { - return delegate.getPolicyEnforcer(); - } - - @Override - public void setPolicyEnforcer(Callable policyEnforcer) { - delegate.setPolicyEnforcer(policyEnforcer); - } - - @Override - public void setMinTimeBetweenJwksRequests(int minTimeBetweenJwksRequests) { - delegate.setMinTimeBetweenJwksRequests(minTimeBetweenJwksRequests); - } - - @Override - public int getMinTimeBetweenJwksRequests() { - return delegate.getMinTimeBetweenJwksRequests(); - } - - @Override - public int getPublicKeyCacheTtl() { - return delegate.getPublicKeyCacheTtl(); - } - - @Override - public void setPublicKeyCacheTtl(int publicKeyCacheTtl) { - delegate.setPublicKeyCacheTtl(publicKeyCacheTtl); - } - - @Override - public boolean isVerifyTokenAudience() { - return delegate.isVerifyTokenAudience(); - } - - @Override - public void setVerifyTokenAudience(boolean verifyTokenAudience) { - delegate.setVerifyTokenAudience(verifyTokenAudience); - } - - @Override - public AdapterConfig getAdapterConfig() { - return delegate.getAdapterConfig(); - } - } - - protected KeycloakUriBuilder getBaseBuilder(HttpFacade facade, String base) { - KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(base); - URI request = URI.create(facade.getRequest().getURI()); - String scheme = request.getScheme(); - if (deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) { - scheme = "https"; - if (!request.getScheme().equals(scheme) && request.getPort() != -1) { - log.error("request scheme: " + request.getScheme() + " ssl required"); - throw new RuntimeException("Can't resolve relative url from adapter config."); - } - } - builder.scheme(scheme); - builder.host(request.getHost()); - if (request.getPort() != -1) { - builder.port(request.getPort()); - } - return builder; - } - - - - protected void close(HttpResponse response) { - if (response.getEntity() != null) { - try { - response.getEntity().getContent().close(); - } catch (IOException e) { - - } - } - } - - public void updateDeployment(AdapterConfig config) { - if (null != configResolver) { - throw new IllegalStateException("Cannot parse an adapter config and build an updated deployment when on a multi-tenant scenario."); - } - deployment = KeycloakDeploymentBuilder.build(config); - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AdapterUtils.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AdapterUtils.java deleted file mode 100755 index cda1635931..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AdapterUtils.java +++ /dev/null @@ -1,116 +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.adapters; - -import org.apache.http.NameValuePair; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.message.BasicNameValuePair; -import org.jboss.logging.Logger; -import org.keycloak.KeycloakPrincipal; -import org.keycloak.protocol.oidc.client.authentication.ClientCredentialsProviderUtils; -import org.keycloak.representations.AccessToken; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -/** - * @author Marek Posolda - */ -public class AdapterUtils { - - private static Logger log = Logger.getLogger(AdapterUtils.class); - - public static String generateId() { - return UUID.randomUUID().toString(); - } - - public static Set getRolesFromSecurityContext(RefreshableKeycloakSecurityContext session) { - Set roles = null; - AccessToken accessToken = session.getToken(); - if (session.getDeployment().isUseResourceRoleMappings()) { - if (log.isTraceEnabled()) { - log.trace("useResourceRoleMappings"); - } - AccessToken.Access access = accessToken.getResourceAccess(session.getDeployment().getResourceName()); - if (access != null) roles = access.getRoles(); - } else { - if (log.isTraceEnabled()) { - log.trace("use realm role mappings"); - } - AccessToken.Access access = accessToken.getRealmAccess(); - if (access != null) roles = access.getRoles(); - } - if (roles == null) roles = Collections.emptySet(); - if (log.isTraceEnabled()) { - log.trace("Setting roles: "); - for (String role : roles) { - log.trace(" role: " + role); - } - } - return roles; - } - - public static String getPrincipalName(KeycloakDeployment deployment, AccessToken token) { - String attr = "sub"; - if (deployment.getPrincipalAttribute() != null) attr = deployment.getPrincipalAttribute(); - String name = null; - - if ("sub".equals(attr)) { - name = token.getSubject(); - } else if ("email".equals(attr)) { - name = token.getEmail(); - } else if ("preferred_username".equals(attr)) { - name = token.getPreferredUsername(); - } else if ("name".equals(attr)) { - name = token.getName(); - } else if ("given_name".equals(attr)) { - name = token.getGivenName(); - } else if ("family_name".equals(attr)) { - name = token.getFamilyName(); - } else if ("nickname".equals(attr)) { - name = token.getNickName(); - } - if (name == null) name = token.getSubject(); - return name; - } - - public static KeycloakPrincipal createPrincipal(KeycloakDeployment deployment, RefreshableKeycloakSecurityContext securityContext) { - return new KeycloakPrincipal<>(getPrincipalName(deployment, securityContext.getToken()), securityContext); - } - - /** - * Don't use directly from your JEE apps to avoid HttpClient linkage errors! Instead use the method {@link #setClientCredentials(KeycloakDeployment, Map, Map)} - */ - public static void setClientCredentials(KeycloakDeployment deployment, HttpPost post, List formparams) { - Map reqHeaders = new HashMap<>(); - Map reqParams = new HashMap<>(); - ClientCredentialsProviderUtils.setClientCredentials(deployment.getAdapterConfig(), deployment.getClientAuthenticator(), reqHeaders, reqParams); - - for (Map.Entry header : reqHeaders.entrySet()) { - post.setHeader(header.getKey(), header.getValue()); - } - - for (Map.Entry param : reqParams.entrySet()) { - formparams.add(new BasicNameValuePair(param.getKey(), param.getValue())); - } - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java deleted file mode 100755 index 77249e8510..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java +++ /dev/null @@ -1,172 +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.adapters; - -import org.keycloak.adapters.pep.HttpAuthzRequest; -import org.keycloak.adapters.pep.HttpAuthzResponse; -import org.jboss.logging.Logger; -import org.keycloak.AuthorizationContext; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.common.util.UriUtils; -import org.keycloak.constants.AdapterConstants; -import org.keycloak.representations.AccessToken; - -import java.io.IOException; -import java.util.Set; - -/** - * Pre-installed actions that must be authenticated - * - * Actions include: - * - * CORS Origin Check and Response headers - * k_query_bearer_token: Get bearer token from server for Javascripts CORS requests - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class AuthenticatedActionsHandler { - private static final Logger log = Logger.getLogger(AuthenticatedActionsHandler.class); - protected KeycloakDeployment deployment; - protected OIDCHttpFacade facade; - - public AuthenticatedActionsHandler(KeycloakDeployment deployment, OIDCHttpFacade facade) { - this.deployment = deployment; - this.facade = facade; - } - - public boolean handledRequest() { - log.debugv("AuthenticatedActionsValve.invoke {0}", facade.getRequest().getURI()); - if (corsRequest()) return true; - String requestUri = facade.getRequest().getURI(); - if (requestUri.endsWith(AdapterConstants.K_QUERY_BEARER_TOKEN)) { - queryBearerToken(); - return true; - } - if (!isAuthorized()) { - return true; - } - return false; - } - - protected void queryBearerToken() { - log.debugv("queryBearerToken {0}",facade.getRequest().getURI()); - if (abortTokenResponse()) return; - facade.getResponse().setStatus(200); - facade.getResponse().setHeader("Content-Type", "text/plain"); - try { - facade.getResponse().getOutputStream().write(facade.getSecurityContext().getTokenString().getBytes()); - } catch (IOException e) { - throw new RuntimeException(e); - } - facade.getResponse().end(); - } - - protected boolean abortTokenResponse() { - if (facade.getSecurityContext() == null) { - log.debugv("Not logged in, sending back 401: {0}",facade.getRequest().getURI()); - facade.getResponse().sendError(401); - facade.getResponse().end(); - return true; - } - if (!deployment.isExposeToken()) { - facade.getResponse().setStatus(200); - facade.getResponse().end(); - return true; - } - // Don't allow a CORS request if we're not validating CORS requests. - String origin = facade.getRequest().getHeader(CorsHeaders.ORIGIN); - if (!deployment.isCors() && origin != null && !origin.equals("null")) { - facade.getResponse().setStatus(200); - facade.getResponse().end(); - return true; - } - return false; - } - - protected boolean corsRequest() { - if (!deployment.isCors()) return false; - KeycloakSecurityContext securityContext = facade.getSecurityContext(); - String origin = facade.getRequest().getHeader(CorsHeaders.ORIGIN); - origin = "null".equals(origin) ? null : origin; - String exposeHeaders = deployment.getCorsExposedHeaders(); - - if (deployment.getPolicyEnforcer() != null) { - if (exposeHeaders != null) { - exposeHeaders += ","; - } else { - exposeHeaders = ""; - } - - exposeHeaders += "WWW-Authenticate"; - } - - String requestOrigin = UriUtils.getOrigin(facade.getRequest().getURI()); - log.debugv("Origin: {0} uri: {1}", origin, facade.getRequest().getURI()); - if (securityContext != null && origin != null && !origin.equals(requestOrigin)) { - AccessToken token = securityContext.getToken(); - Set allowedOrigins = token.getAllowedOrigins(); - - log.debugf("Allowed origins in token: %s", allowedOrigins); - - if (allowedOrigins == null || (!allowedOrigins.contains("*") && !allowedOrigins.contains(origin))) { - if (allowedOrigins == null) { - log.debugv("allowedOrigins was null in token"); - } else { - log.debugv("allowedOrigins did not contain origin"); - } - facade.getResponse().sendError(403); - facade.getResponse().end(); - return true; - } - log.debugv("returning origin: {0}", origin); - facade.getResponse().setStatus(200); - facade.getResponse().setHeader(CorsHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin); - facade.getResponse().setHeader(CorsHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); - if (exposeHeaders != null) { - facade.getResponse().setHeader(CorsHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, exposeHeaders); - } - } else { - log.debugv("cors validation not needed as we are not a secure session or origin header was null: {0}", facade.getRequest().getURI()); - } - return false; - } - - private boolean isAuthorized() { - PolicyEnforcer policyEnforcer = this.deployment.getPolicyEnforcer(); - - if (policyEnforcer == null) { - log.debugv("Policy enforcement is disabled."); - return true; - } - try { - OIDCHttpFacade facade = (OIDCHttpFacade) this.facade; - AuthorizationContext authorizationContext = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); - RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) facade.getSecurityContext(); - - if (session != null) { - session.setAuthorizationContext(authorizationContext); - } - - return authorizationContext.isGranted(); - } catch (Exception e) { - throw new RuntimeException("Failed to enforce policy decisions.", e); - } - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/CorsHeaders.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/CorsHeaders.java deleted file mode 100755 index 416c3923f8..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/CorsHeaders.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.adapters; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface CorsHeaders { - String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; - String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; - String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"; - String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"; - String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age"; - String ORIGIN = "Origin"; - String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method"; - String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers"; - String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers"; -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java deleted file mode 100644 index 6a3176a3b9..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java +++ /dev/null @@ -1,71 +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.adapters; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpRequestBase; -import org.keycloak.util.JsonSerialization; - -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Marek Posolda - */ -public class HttpAdapterUtils { - - - public static T sendJsonHttpRequest(KeycloakDeployment deployment, HttpRequestBase httpRequest, Class clazz) throws HttpClientAdapterException { - try { - HttpResponse response = deployment.getClient().execute(httpRequest); - int status = response.getStatusLine().getStatusCode(); - if (status != 200) { - close(response); - throw new HttpClientAdapterException("Unexpected status = " + status); - } - HttpEntity entity = response.getEntity(); - if (entity == null) { - throw new HttpClientAdapterException("There was no entity."); - } - InputStream is = entity.getContent(); - try { - return JsonSerialization.readValue(is, clazz); - } finally { - try { - is.close(); - } catch (IOException ignored) { - - } - } - } catch (IOException e) { - throw new HttpClientAdapterException("IO error", e); - } - } - - - private static void close(HttpResponse response) { - if (response.getEntity() != null) { - try { - response.getEntity().getContent().close(); - } catch (IOException e) { - - } - } - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpClientAdapterException.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpClientAdapterException.java deleted file mode 100644 index 7d303e290d..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpClientAdapterException.java +++ /dev/null @@ -1,32 +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.adapters; - -/** - * @author Marek Posolda - */ -public class HttpClientAdapterException extends Exception { - - public HttpClientAdapterException(String message) { - super(message); - } - - public HttpClientAdapterException(String message, Throwable t) { - super(message, t); - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpClientBuilder.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpClientBuilder.java deleted file mode 100755 index 7338f220a6..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/HttpClientBuilder.java +++ /dev/null @@ -1,477 +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.adapters; - -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthSchemeProvider; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.Credentials; -import org.apache.http.client.CookieStore; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.AuthSchemes; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.config.ConnectionConfig; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.config.SocketConfig; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.AllowAllHostnameVerifier; -import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.StrictHostnameVerifier; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.cookie.Cookie; -import org.apache.http.cookie.CookieSpecProvider; -import org.apache.http.impl.auth.SPNegoSchemeFactory; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CookieSpecRegistries; -import org.apache.http.impl.conn.BasicHttpClientConnectionManager; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.impl.cookie.DefaultCookieSpecProvider; -import org.keycloak.common.util.EnvUtil; -import org.keycloak.common.util.KeystoreUtil; -import org.keycloak.representations.adapters.config.AdapterHttpClientConfig; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; -import java.io.IOException; -import java.net.URI; -import java.security.KeyStore; -import java.security.Principal; -import java.security.SecureRandom; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Abstraction for creating HttpClients. Allows SSL configuration. - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class HttpClientBuilder { - - public static enum HostnameVerificationPolicy { - /** - * Hostname verification is not done on the server's certificate - */ - ANY, - /** - * Allows wildcards in subdomain names i.e. *.foo.com - */ - WILDCARD, - /** - * CN must match hostname connecting to - */ - STRICT - } - - - /** - * @author Bill Burke - * @version $Revision: 1 $ - */ - private static class PassthroughTrustManager implements X509TrustManager { - public void checkClientTrusted(X509Certificate[] chain, - String authType) throws CertificateException { - } - - public void checkServerTrusted(X509Certificate[] chain, - String authType) throws CertificateException { - } - - public X509Certificate[] getAcceptedIssuers() { - return null; - } - } - - protected KeyStore truststore; - protected KeyStore clientKeyStore; - protected String clientPrivateKeyPassword; - protected boolean disableTrustManager; - protected boolean disableCookieCache = true; - protected HostnameVerificationPolicy policy = HostnameVerificationPolicy.WILDCARD; - protected SSLContext sslContext; - protected int connectionPoolSize = 100; - protected int maxPooledPerRoute = 0; - protected long connectionTTL = -1; - protected TimeUnit connectionTTLUnit = TimeUnit.MILLISECONDS; - protected HostnameVerifier verifier = null; - protected long socketTimeout = -1; - protected TimeUnit socketTimeoutUnits = TimeUnit.MILLISECONDS; - protected long establishConnectionTimeout = -1; - protected TimeUnit establishConnectionTimeoutUnits = TimeUnit.MILLISECONDS; - protected HttpHost proxyHost; - private SPNegoSchemeFactory spNegoSchemeFactory; - private boolean useSpNego; - - /** - * Socket inactivity timeout - * - * @param timeout - * @param unit - * @return - */ - public HttpClientBuilder socketTimeout(long timeout, TimeUnit unit) { - this.socketTimeout = timeout; - this.socketTimeoutUnits = unit; - return this; - } - - /** - * When trying to make an initial socket connection, what is the timeout? - * - * @param timeout - * @param unit - * @return - */ - public HttpClientBuilder establishConnectionTimeout(long timeout, TimeUnit unit) { - this.establishConnectionTimeout = timeout; - this.establishConnectionTimeoutUnits = unit; - return this; - } - - public HttpClientBuilder connectionTTL(long ttl, TimeUnit unit) { - this.connectionTTL = ttl; - this.connectionTTLUnit = unit; - return this; - } - - public HttpClientBuilder maxPooledPerRoute(int maxPooledPerRoute) { - this.maxPooledPerRoute = maxPooledPerRoute; - return this; - } - - public HttpClientBuilder connectionPoolSize(int connectionPoolSize) { - this.connectionPoolSize = connectionPoolSize; - return this; - } - - /** - * Disable trust management and hostname verification. NOTE this is a security - * hole, so only set this option if you cannot or do not want to verify the identity of the - * host you are communicating with. - */ - public HttpClientBuilder disableTrustManager() { - this.disableTrustManager = true; - return this; - } - - public HttpClientBuilder disableCookieCache(boolean disable) { - this.disableCookieCache = disable; - return this; - } - - /** - * SSL policy used to verify hostnames - * - * @param policy - * @return - */ - public HttpClientBuilder hostnameVerification(HostnameVerificationPolicy policy) { - this.policy = policy; - return this; - } - - - public HttpClientBuilder sslContext(SSLContext sslContext) { - this.sslContext = sslContext; - return this; - } - - public HttpClientBuilder trustStore(KeyStore truststore) { - this.truststore = truststore; - return this; - } - - public HttpClientBuilder keyStore(KeyStore keyStore, String password) { - this.clientKeyStore = keyStore; - this.clientPrivateKeyPassword = password; - return this; - } - - public HttpClientBuilder keyStore(KeyStore keyStore, char[] password) { - this.clientKeyStore = keyStore; - this.clientPrivateKeyPassword = new String(password); - return this; - } - - - static class VerifierWrapper implements X509HostnameVerifier { - protected HostnameVerifier verifier; - - VerifierWrapper(HostnameVerifier verifier) { - this.verifier = verifier; - } - - @Override - public void verify(String host, SSLSocket ssl) throws IOException { - if (!verifier.verify(host, ssl.getSession())) throw new SSLException("Hostname verification failure"); - } - - @Override - public void verify(String host, X509Certificate cert) throws SSLException { - throw new SSLException("This verification path not implemented"); - } - - @Override - public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException { - throw new SSLException("This verification path not implemented"); - } - - @Override - public boolean verify(String s, SSLSession sslSession) { - return verifier.verify(s, sslSession); - } - } - - public HttpClientBuilder spNegoSchemeFactory(SPNegoSchemeFactory spnegoSchemeFactory) { - this.spNegoSchemeFactory = spnegoSchemeFactory; - return this; - } - - public HttpClientBuilder useSPNego(boolean useSpnego) { - this.useSpNego = useSpnego; - return this; - } - - public HttpClient build() { - X509HostnameVerifier verifier = null; - if (this.verifier != null) verifier = new VerifierWrapper(this.verifier); - else { - switch (policy) { - case ANY: - verifier = new AllowAllHostnameVerifier(); - break; - case WILDCARD: - verifier = new BrowserCompatHostnameVerifier(); - break; - case STRICT: - verifier = new StrictHostnameVerifier(); - break; - } - } - try { - ConnectionSocketFactory sslsf; - SSLContext theContext = sslContext; - if (disableTrustManager) { - theContext = SSLContext.getInstance("SSL"); - theContext.init(null, new TrustManager[]{new PassthroughTrustManager()}, - new SecureRandom()); - verifier = new AllowAllHostnameVerifier(); - sslsf = new SniSSLSocketFactory(theContext, verifier); - } else if (theContext != null) { - sslsf = new SniSSLSocketFactory(theContext, verifier); - } else if (clientKeyStore != null || truststore != null) { - sslsf = new SniSSLSocketFactory(SSLSocketFactory.TLS, clientKeyStore, clientPrivateKeyPassword, truststore, null, verifier); - } else { - final SSLContext tlsContext = SSLContext.getInstance(SSLSocketFactory.TLS); - tlsContext.init(null, null, null); - sslsf = new SniSSLSocketFactory(tlsContext, verifier); - } - - RegistryBuilder sf = RegistryBuilder.create(); - - sf.register("http", PlainConnectionSocketFactory.getSocketFactory()); - sf.register("https", sslsf); - - HttpClientConnectionManager cm; - - if (connectionPoolSize > 0) { - PoolingHttpClientConnectionManager tcm = new PoolingHttpClientConnectionManager(sf.build(), null, null, null, connectionTTL, connectionTTLUnit); - tcm.setMaxTotal(connectionPoolSize); - if (maxPooledPerRoute == 0) maxPooledPerRoute = connectionPoolSize; - tcm.setDefaultMaxPerRoute(maxPooledPerRoute); - cm = tcm; - - } else { - cm = new BasicHttpClientConnectionManager(sf.build()); - } - - SocketConfig.Builder socketConfig = SocketConfig.copy(SocketConfig.DEFAULT); - ConnectionConfig.Builder connConfig = ConnectionConfig.copy(ConnectionConfig.DEFAULT); - RequestConfig.Builder requestConfig = RequestConfig.copy(RequestConfig.DEFAULT); - - if (proxyHost != null) { - requestConfig.setProxy(new HttpHost(proxyHost)); - } - - if (socketTimeout > -1) { - requestConfig.setSocketTimeout((int) socketTimeoutUnits.toMillis(socketTimeout)); - - } - if (establishConnectionTimeout > -1) { - requestConfig.setConnectTimeout((int) establishConnectionTimeoutUnits.toMillis(establishConnectionTimeout)); - } - - Registry cookieSpecs = CookieSpecRegistries.createDefaultBuilder() - .register(CookieSpecs.DEFAULT, new DefaultCookieSpecProvider()).build(); - - if (useSpNego) { - requestConfig.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.SPNEGO)); - } - - org.apache.http.impl.client.HttpClientBuilder clientBuilder = org.apache.http.impl.client.HttpClientBuilder.create() - .setDefaultSocketConfig(socketConfig.build()) - .setDefaultConnectionConfig(connConfig.build()) - .setDefaultRequestConfig(requestConfig.build()) - .setDefaultCookieSpecRegistry(cookieSpecs) - .setConnectionManager(cm); - - if (spNegoSchemeFactory != null) { - RegistryBuilder authSchemes = RegistryBuilder.create(); - - authSchemes.register(AuthSchemes.SPNEGO, spNegoSchemeFactory); - - clientBuilder.setDefaultAuthSchemeRegistry(authSchemes.build()); - } - - if (useSpNego) { - Credentials fake = new Credentials() { - - @Override - public String getPassword() { - return null; - } - - @Override - public Principal getUserPrincipal() { - return null; - } - - }; - - BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, fake); - clientBuilder.setDefaultCredentialsProvider(credentialsProvider); - } - - if (disableCookieCache) { - clientBuilder.setDefaultCookieStore(new CookieStore() { - @Override - public void addCookie(Cookie cookie) { - //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public List getCookies() { - return Collections.emptyList(); - } - - @Override - public boolean clearExpired(Date date) { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public void clear() { - //To change body of implemented methods use File | Settings | File Templates. - } - }); - - } - return clientBuilder.build(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public HttpClient build(AdapterHttpClientConfig adapterConfig) { - disableCookieCache(true); // disable cookie cache as we don't want sticky sessions for load balancing - - String truststorePath = adapterConfig.getTruststore(); - if (truststorePath != null) { - truststorePath = EnvUtil.replace(truststorePath); - String truststorePassword = adapterConfig.getTruststorePassword(); - try { - this.truststore = KeystoreUtil.loadKeyStore(truststorePath, truststorePassword); - } catch (Exception e) { - throw new RuntimeException("Failed to load truststore", e); - } - } - String clientKeystore = adapterConfig.getClientKeystore(); - if (clientKeystore != null) { - clientKeystore = EnvUtil.replace(clientKeystore); - String clientKeystorePassword = adapterConfig.getClientKeystorePassword(); - try { - KeyStore clientCertKeystore = KeystoreUtil.loadKeyStore(clientKeystore, clientKeystorePassword); - keyStore(clientCertKeystore, clientKeystorePassword); - } catch (Exception e) { - throw new RuntimeException("Failed to load keystore", e); - } - } - - HttpClientBuilder.HostnameVerificationPolicy policy = HttpClientBuilder.HostnameVerificationPolicy.WILDCARD; - if (adapterConfig.isAllowAnyHostname()) - policy = HttpClientBuilder.HostnameVerificationPolicy.ANY; - connectionPoolSize(adapterConfig.getConnectionPoolSize()); - hostnameVerification(policy); - if (adapterConfig.isDisableTrustManager()) { - disableTrustManager(); - } else { - trustStore(truststore); - } - - configureProxyForAuthServerIfProvided(adapterConfig); - - if (socketTimeout == -1 && adapterConfig.getSocketTimeout() > 0) { - socketTimeout(adapterConfig.getSocketTimeout(), TimeUnit.MILLISECONDS); - } - - if (establishConnectionTimeout == -1 && adapterConfig.getConnectionTimeout() > 0) { - establishConnectionTimeout(adapterConfig.getConnectionTimeout(), TimeUnit.MILLISECONDS); - } - - if (connectionTTL == -1 && adapterConfig.getConnectionTTL() > 0) { - connectionTTL(adapterConfig.getConnectionTTL(), TimeUnit.MILLISECONDS); - } - - return build(); - } - - /** - * Configures a the proxy to use for auth-server requests if provided. - *

- * If the given {@link AdapterHttpClientConfig} contains the attribute {@code proxy-url} we use the - * given URL as a proxy server, otherwise the proxy configuration is ignored. - *

- * - * @param adapterConfig - */ - private void configureProxyForAuthServerIfProvided(AdapterHttpClientConfig adapterConfig) { - - if (adapterConfig == null || adapterConfig.getProxyUrl() == null || adapterConfig.getProxyUrl().trim().isEmpty()) { - return; - } - - URI uri = URI.create(adapterConfig.getProxyUrl()); - this.proxyHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); - } -} \ No newline at end of file diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakConfigResolver.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakConfigResolver.java deleted file mode 100644 index 987adaecef..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakConfigResolver.java +++ /dev/null @@ -1,48 +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.adapters; - -import org.keycloak.adapters.spi.HttpFacade.Request; - -/** - * On multi-tenant scenarios, Keycloak will defer the resolution of a - * KeycloakDeployment to the target application at the request-phase. - * - * A Request object is passed to the resolver and callers expect a complete - * KeycloakDeployment. Based on this KeycloakDeployment, Keycloak will resume - * authenticating and authorizing the request. - * - * The easiest way to build a KeycloakDeployment is to use - * KeycloakDeploymentBuilder , passing the InputStream of an existing - * keycloak.json to the build() method. - * - * The resolved KeycloakDeployment may not be null - * - * @see KeycloakDeploymentBuilder - * @author Juraci Paixão Kröhling - */ -public interface KeycloakConfigResolver { - - /** - * Resolves the KeycloakDeployment based on the Request - * - * @param facade The request - * @return KeycloakDeployment, may never be null - */ - public KeycloakDeployment resolve(Request facade); - -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakDeployment.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakDeployment.java deleted file mode 100755 index eebe9bedee..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakDeployment.java +++ /dev/null @@ -1,608 +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.adapters; - -import org.keycloak.adapters.rotation.PublicKeyLocator; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.util.EntityUtils; -import org.jboss.logging.Logger; -import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.common.enums.RelativeUrlsUsed; -import org.keycloak.common.enums.SslRequired; -import org.keycloak.common.util.KeycloakUriBuilder; -import org.keycloak.constants.ServiceUrlConstants; -import org.keycloak.enums.TokenStore; -import org.keycloak.protocol.oidc.client.authentication.ClientCredentialsProvider; -import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation; -import org.keycloak.representations.adapters.config.AdapterConfig; -import org.keycloak.util.JsonSerialization; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Callable; - -/** - * @author Bill Burke - * @author Brad Culley - * @author John D. Ament - * @version $Revision: 1 $ - */ -public class KeycloakDeployment { - - private static final Logger log = Logger.getLogger(KeycloakDeployment.class); - - protected RelativeUrlsUsed relativeUrls; - protected String realm; - protected PublicKeyLocator publicKeyLocator; - protected String authServerBaseUrl; - protected String realmInfoUrl; - protected KeycloakUriBuilder authUrl; - protected String tokenUrl; - protected KeycloakUriBuilder logoutUrl; - protected String accountUrl; - protected String registerNodeUrl; - protected String unregisterNodeUrl; - protected String jwksUrl; - protected String principalAttribute = "sub"; - - protected String resourceName; - protected boolean bearerOnly; - protected boolean autodetectBearerOnly; - protected boolean enableBasicAuth; - protected boolean publicClient; - protected Map resourceCredentials = new HashMap<>(); - protected ClientCredentialsProvider clientAuthenticator; - protected Callable client; - - protected String scope; - protected SslRequired sslRequired = SslRequired.ALL; - protected int confidentialPort = -1; - protected TokenStore tokenStore = TokenStore.SESSION; - protected String adapterStateCookiePath = ""; - protected String stateCookieName = "OAuth_Token_Request_State"; - protected boolean useResourceRoleMappings; - protected boolean cors; - protected int corsMaxAge = -1; - protected String corsAllowedHeaders; - protected String corsAllowedMethods; - protected String corsExposedHeaders; - protected boolean exposeToken; - protected boolean alwaysRefreshToken; - protected boolean registerNodeAtStartup; - protected int registerNodePeriod; - protected boolean turnOffChangeSessionIdOnLogin; - - protected volatile int notBefore; - protected int tokenMinimumTimeToLive; - protected int minTimeBetweenJwksRequests; - protected int publicKeyCacheTtl; - protected Callable policyEnforcer; - - // https://tools.ietf.org/html/rfc7636 - protected boolean pkce = false; - protected boolean ignoreOAuthQueryParameter; - - protected Map redirectRewriteRules; - - protected boolean delegateBearerErrorResponseSending = false; - protected boolean verifyTokenAudience = false; - private AdapterConfig adapterConfig; - - public KeycloakDeployment() { - } - - public boolean isConfigured() { - return getRealm() != null && getPublicKeyLocator() != null && (isBearerOnly() || getAuthServerBaseUrl() != null); - } - - public String getResourceName() { - return resourceName; - } - - public String getRealm() { - return realm; - } - - public void setRealm(String realm) { - this.realm = realm; - } - - public PublicKeyLocator getPublicKeyLocator() { - return publicKeyLocator; - } - - public void setPublicKeyLocator(PublicKeyLocator publicKeyLocator) { - this.publicKeyLocator = publicKeyLocator; - } - - public String getAuthServerBaseUrl() { - return authServerBaseUrl; - } - - public void setAuthServerBaseUrl(AdapterConfig config) { - this.authServerBaseUrl = config.getAuthServerUrl(); - if (authServerBaseUrl == null) return; - - authServerBaseUrl = KeycloakUriBuilder.fromUri(authServerBaseUrl).build().toString(); - - authUrl = null; - realmInfoUrl = null; - tokenUrl = null; - logoutUrl = null; - accountUrl = null; - registerNodeUrl = null; - unregisterNodeUrl = null; - jwksUrl = null; - - URI authServerUri = URI.create(authServerBaseUrl); - - if (authServerUri.getHost() == null) { - relativeUrls = RelativeUrlsUsed.ALWAYS; - } else { - // We have absolute URI in config - relativeUrls = RelativeUrlsUsed.NEVER; - } - - this.adapterConfig = config; - } - - /** - * URLs are loaded lazily when used. This allows adapter to be deployed prior to Keycloak server starting, and will - * also allow the adapter to retry loading config for each request until the Keycloak server is ready. - * - * In the future we may want to support reloading config at a configurable interval. - */ - protected void resolveUrls() { - if (realmInfoUrl == null) { - synchronized (this) { - if (realmInfoUrl == null) { - KeycloakUriBuilder authUrlBuilder = KeycloakUriBuilder - .fromUri(authServerBaseUrl); - - String discoveryUrl = authUrlBuilder.clone() - .path(ServiceUrlConstants.DISCOVERY_URL).build(getRealm()).toString(); - try { - log.debugv("Resolving URLs from {0}", discoveryUrl); - - OIDCConfigurationRepresentation config = getOidcConfiguration(discoveryUrl); - - authUrl = KeycloakUriBuilder.fromUri(config.getAuthorizationEndpoint()); - realmInfoUrl = config.getIssuer(); - - tokenUrl = config.getTokenEndpoint(); - logoutUrl = KeycloakUriBuilder.fromUri(config.getLogoutEndpoint()); - accountUrl = KeycloakUriBuilder.fromUri(config.getIssuer()).path("/account") - .build().toString(); - registerNodeUrl = authUrlBuilder.clone() - .path(ServiceUrlConstants.CLIENTS_MANAGEMENT_REGISTER_NODE_PATH) - .build(getRealm()).toString(); - unregisterNodeUrl = authUrlBuilder.clone() - .path(ServiceUrlConstants.CLIENTS_MANAGEMENT_UNREGISTER_NODE_PATH) - .build(getRealm()).toString(); - jwksUrl = config.getJwksUri(); - - log.infov("Loaded URLs from {0}", discoveryUrl); - } catch (Exception e) { - log.warnv(e, "Failed to load URLs from {0}", discoveryUrl); - } - } - } - } - } - - protected void resolveUrls(KeycloakUriBuilder authUrlBuilder) { - if (log.isDebugEnabled()) { - log.debug("resolveUrls"); - } - - String login = authUrlBuilder.clone().path(ServiceUrlConstants.AUTH_PATH).build(getRealm()).toString(); - authUrl = KeycloakUriBuilder.fromUri(login); - realmInfoUrl = authUrlBuilder.clone().path(ServiceUrlConstants.REALM_INFO_PATH).build(getRealm()).toString(); - - tokenUrl = authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_PATH).build(getRealm()).toString(); - logoutUrl = KeycloakUriBuilder.fromUri(authUrlBuilder.clone().path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH).build(getRealm()).toString()); - accountUrl = authUrlBuilder.clone().path(ServiceUrlConstants.ACCOUNT_SERVICE_PATH).build(getRealm()).toString(); - registerNodeUrl = authUrlBuilder.clone().path(ServiceUrlConstants.CLIENTS_MANAGEMENT_REGISTER_NODE_PATH).build(getRealm()).toString(); - unregisterNodeUrl = authUrlBuilder.clone().path(ServiceUrlConstants.CLIENTS_MANAGEMENT_UNREGISTER_NODE_PATH).build(getRealm()).toString(); - jwksUrl = authUrlBuilder.clone().path(ServiceUrlConstants.JWKS_URL).build(getRealm()).toString(); - } - - protected OIDCConfigurationRepresentation getOidcConfiguration(String discoveryUrl) throws Exception { - HttpGet request = new HttpGet(discoveryUrl); - request.addHeader("accept", "application/json"); - - try { - HttpResponse response = getClient().execute(request); - if (response.getStatusLine().getStatusCode() != 200) { - EntityUtils.consumeQuietly(response.getEntity()); - throw new Exception(response.getStatusLine().getReasonPhrase()); - } - return JsonSerialization.readValue(response.getEntity().getContent(), OIDCConfigurationRepresentation.class); - } finally { - request.releaseConnection(); - } - } - - public RelativeUrlsUsed getRelativeUrls() { - return relativeUrls; - } - - public String getRealmInfoUrl() { - resolveUrls(); - return realmInfoUrl; - } - - public KeycloakUriBuilder getAuthUrl() { - resolveUrls(); - return authUrl; - } - - public String getTokenUrl() { - resolveUrls(); - return tokenUrl; - } - - public KeycloakUriBuilder getLogoutUrl() { - resolveUrls(); - return logoutUrl; - } - - public String getAccountUrl() { - resolveUrls(); - return accountUrl; - } - - public String getRegisterNodeUrl() { - resolveUrls(); - return registerNodeUrl; - } - - public String getUnregisterNodeUrl() { - resolveUrls(); - return unregisterNodeUrl; - } - - public String getJwksUrl() { - resolveUrls(); - return jwksUrl; - } - - public void setResourceName(String resourceName) { - this.resourceName = resourceName; - } - - public boolean isBearerOnly() { - return bearerOnly; - } - - public void setBearerOnly(boolean bearerOnly) { - this.bearerOnly = bearerOnly; - } - - public boolean isAutodetectBearerOnly() { - return autodetectBearerOnly; - } - - public void setAutodetectBearerOnly(boolean autodetectBearerOnly) { - this.autodetectBearerOnly = autodetectBearerOnly; - } - - public boolean isEnableBasicAuth() { - return enableBasicAuth; - } - - public void setEnableBasicAuth(boolean enableBasicAuth) { - this.enableBasicAuth = enableBasicAuth; - } - - public boolean isPublicClient() { - return publicClient; - } - - public void setPublicClient(boolean publicClient) { - this.publicClient = publicClient; - } - - public Map getResourceCredentials() { - return resourceCredentials; - } - - public void setResourceCredentials(Map resourceCredentials) { - this.resourceCredentials = resourceCredentials; - } - - public ClientCredentialsProvider getClientAuthenticator() { - return clientAuthenticator; - } - - public void setClientAuthenticator(ClientCredentialsProvider clientAuthenticator) { - this.clientAuthenticator = clientAuthenticator; - } - - public HttpClient getClient() { - try { - return client.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public void setClient(final HttpClient client) { - this.client = new Callable() { - @Override - public HttpClient call() { - return client; - } - }; - } - - public String getScope() { - return scope; - } - - public void setScope(String scope) { - this.scope = scope; - } - - public SslRequired getSslRequired() { - return sslRequired; - } - - public void setSslRequired(SslRequired sslRequired) { - this.sslRequired = sslRequired; - } - - public boolean isSSLEnabled() { - if (SslRequired.NONE == sslRequired) { - return false; - } - return true; - } - - public int getConfidentialPort() { - return confidentialPort; - } - - public void setConfidentialPort(int confidentialPort) { - this.confidentialPort = confidentialPort; - } - - public TokenStore getTokenStore() { - return tokenStore; - } - - public void setTokenStore(TokenStore tokenStore) { - this.tokenStore = tokenStore; - } - - public String getAdapterStateCookiePath() { - return adapterStateCookiePath; - } - - public void setAdapterStateCookiePath(String adapterStateCookiePath) { - this.adapterStateCookiePath = adapterStateCookiePath; - } - - public String getStateCookieName() { - return stateCookieName; - } - - public void setStateCookieName(String stateCookieName) { - this.stateCookieName = stateCookieName; - } - - public boolean isUseResourceRoleMappings() { - return useResourceRoleMappings; - } - - public void setUseResourceRoleMappings(boolean useResourceRoleMappings) { - this.useResourceRoleMappings = useResourceRoleMappings; - } - - public boolean isCors() { - return cors; - } - - public void setCors(boolean cors) { - this.cors = cors; - } - - public int getCorsMaxAge() { - return corsMaxAge; - } - - public void setCorsMaxAge(int corsMaxAge) { - this.corsMaxAge = corsMaxAge; - } - - public String getCorsAllowedHeaders() { - return corsAllowedHeaders; - } - - public void setCorsAllowedHeaders(String corsAllowedHeaders) { - this.corsAllowedHeaders = corsAllowedHeaders; - } - - public String getCorsAllowedMethods() { - return corsAllowedMethods; - } - - public void setCorsAllowedMethods(String corsAllowedMethods) { - this.corsAllowedMethods = corsAllowedMethods; - } - - public String getCorsExposedHeaders() { - return corsExposedHeaders; - } - - public void setCorsExposedHeaders(String corsExposedHeaders) { - this.corsExposedHeaders = corsExposedHeaders; - } - - public boolean isExposeToken() { - return exposeToken; - } - - public void setExposeToken(boolean exposeToken) { - this.exposeToken = exposeToken; - } - - public int getNotBefore() { - return notBefore; - } - - public void setNotBefore(int notBefore) { - this.notBefore = notBefore; - } - - public void updateNotBefore(int notBefore) { - this.notBefore = notBefore; - getPublicKeyLocator().reset(this); - } - - public boolean isAlwaysRefreshToken() { - return alwaysRefreshToken; - } - - public void setAlwaysRefreshToken(boolean alwaysRefreshToken) { - this.alwaysRefreshToken = alwaysRefreshToken; - } - - public boolean isRegisterNodeAtStartup() { - return registerNodeAtStartup; - } - - public void setRegisterNodeAtStartup(boolean registerNodeAtStartup) { - this.registerNodeAtStartup = registerNodeAtStartup; - } - - public int getRegisterNodePeriod() { - return registerNodePeriod; - } - - public void setRegisterNodePeriod(int registerNodePeriod) { - this.registerNodePeriod = registerNodePeriod; - } - - public String getPrincipalAttribute() { - return principalAttribute; - } - - public void setPrincipalAttribute(String principalAttribute) { - this.principalAttribute = principalAttribute; - } - - public boolean isTurnOffChangeSessionIdOnLogin() { - return turnOffChangeSessionIdOnLogin; - } - - public void setTurnOffChangeSessionIdOnLogin(boolean turnOffChangeSessionIdOnLogin) { - this.turnOffChangeSessionIdOnLogin = turnOffChangeSessionIdOnLogin; - } - - public int getTokenMinimumTimeToLive() { - return tokenMinimumTimeToLive; - } - - public void setTokenMinimumTimeToLive(final int tokenMinimumTimeToLive) { - this.tokenMinimumTimeToLive = tokenMinimumTimeToLive; - } - - public int getMinTimeBetweenJwksRequests() { - return minTimeBetweenJwksRequests; - } - - public void setMinTimeBetweenJwksRequests(int minTimeBetweenJwksRequests) { - this.minTimeBetweenJwksRequests = minTimeBetweenJwksRequests; - } - - public int getPublicKeyCacheTtl() { - return publicKeyCacheTtl; - } - - public void setPublicKeyCacheTtl(int publicKeyCacheTtl) { - this.publicKeyCacheTtl = publicKeyCacheTtl; - } - - public void setPolicyEnforcer(Callable policyEnforcer) { - this.policyEnforcer = policyEnforcer; - } - - public PolicyEnforcer getPolicyEnforcer() { - if (policyEnforcer == null) { - return null; - } - try { - return policyEnforcer.call(); - } catch (Exception cause) { - throw new RuntimeException("Failed to obtain policy enforcer", cause); - } - } - - // https://tools.ietf.org/html/rfc7636 - public boolean isPkce() { - return pkce; - } - - public void setPkce(boolean pkce) { - this.pkce = pkce; - } - - public void setIgnoreOAuthQueryParameter(boolean ignoreOAuthQueryParameter) { - this.ignoreOAuthQueryParameter = ignoreOAuthQueryParameter; - } - - public boolean isOAuthQueryParameterEnabled() { - return !this.ignoreOAuthQueryParameter; - } - - public Map getRedirectRewriteRules() { - return redirectRewriteRules; - } - - public void setRewriteRedirectRules(Map redirectRewriteRules) { - this.redirectRewriteRules = redirectRewriteRules; - } - - public boolean isDelegateBearerErrorResponseSending() { - return delegateBearerErrorResponseSending; - } - - public void setDelegateBearerErrorResponseSending(boolean delegateBearerErrorResponseSending) { - this.delegateBearerErrorResponseSending = delegateBearerErrorResponseSending; - } - - public boolean isVerifyTokenAudience() { - return verifyTokenAudience; - } - - public void setVerifyTokenAudience(boolean verifyTokenAudience) { - this.verifyTokenAudience = verifyTokenAudience; - } - - public void setClient(Callable callable) { - client = callable; - } - - public AdapterConfig getAdapterConfig() { - return adapterConfig; - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java deleted file mode 100755 index 3626362de5..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java +++ /dev/null @@ -1,217 +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.adapters; - -import static org.keycloak.protocol.oidc.client.authentication.ClientCredentialsProviderUtils.bootstrapClientAuthenticator; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.client.HttpClient; -import org.jboss.logging.Logger; -import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.adapters.rotation.HardcodedPublicKeyLocator; -import org.keycloak.adapters.rotation.JWKPublicKeyLocator; -import org.keycloak.common.crypto.CryptoIntegration; -import org.keycloak.common.enums.SslRequired; -import org.keycloak.common.util.PemUtils; -import org.keycloak.enums.TokenStore; -import org.keycloak.representations.adapters.config.AdapterConfig; -import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; -import org.keycloak.util.SystemPropertiesJsonParserFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.security.PublicKey; -import java.util.concurrent.Callable; - -/** - * @author Bill Burke - * @author Brad Culley - * @author John D. Ament - * @version $Revision: 1 $ - */ -public class KeycloakDeploymentBuilder { - - private static final Logger log = Logger.getLogger(KeycloakDeploymentBuilder.class); - - protected KeycloakDeployment deployment = new KeycloakDeployment(); - - protected KeycloakDeploymentBuilder() { - } - - - protected KeycloakDeployment internalBuild(final AdapterConfig adapterConfig) { - if (adapterConfig.getRealm() == null) throw new RuntimeException("Must set 'realm' in config"); - deployment.setRealm(adapterConfig.getRealm()); - String resource = adapterConfig.getResource(); - if (resource == null) throw new RuntimeException("Must set 'resource' in config"); - deployment.setResourceName(resource); - - String realmKeyPem = adapterConfig.getRealmKey(); - if (realmKeyPem != null) { - PublicKey realmKey; - try { - realmKey = PemUtils.decodePublicKey(realmKeyPem); - HardcodedPublicKeyLocator pkLocator = new HardcodedPublicKeyLocator(realmKey); - deployment.setPublicKeyLocator(pkLocator); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - JWKPublicKeyLocator pkLocator = new JWKPublicKeyLocator(); - deployment.setPublicKeyLocator(pkLocator); - } - - if (adapterConfig.getSslRequired() != null) { - deployment.setSslRequired(SslRequired.valueOf(adapterConfig.getSslRequired().toUpperCase())); - } else { - deployment.setSslRequired(SslRequired.EXTERNAL); - } - - if (adapterConfig.getConfidentialPort() != -1) { - deployment.setConfidentialPort(adapterConfig.getConfidentialPort()); - } - - if (adapterConfig.getTokenStore() != null) { - deployment.setTokenStore(TokenStore.valueOf(adapterConfig.getTokenStore().toUpperCase())); - } else { - deployment.setTokenStore(TokenStore.SESSION); - } - if (adapterConfig.getTokenCookiePath() != null) { - deployment.setAdapterStateCookiePath(adapterConfig.getTokenCookiePath()); - } - if (adapterConfig.getPrincipalAttribute() != null) deployment.setPrincipalAttribute(adapterConfig.getPrincipalAttribute()); - - deployment.setResourceCredentials(adapterConfig.getCredentials()); - deployment.setClientAuthenticator(bootstrapClientAuthenticator(adapterConfig)); - - deployment.setPublicClient(adapterConfig.isPublicClient()); - deployment.setUseResourceRoleMappings(adapterConfig.isUseResourceRoleMappings()); - - deployment.setExposeToken(adapterConfig.isExposeToken()); - - if (adapterConfig.isCors()) { - deployment.setCors(true); - deployment.setCorsMaxAge(adapterConfig.getCorsMaxAge()); - deployment.setCorsAllowedHeaders(adapterConfig.getCorsAllowedHeaders()); - deployment.setCorsAllowedMethods(adapterConfig.getCorsAllowedMethods()); - deployment.setCorsExposedHeaders(adapterConfig.getCorsExposedHeaders()); - } - - // https://tools.ietf.org/html/rfc7636 - if (adapterConfig.isPkce()) { - deployment.setPkce(true); - } - - deployment.setBearerOnly(adapterConfig.isBearerOnly()); - deployment.setAutodetectBearerOnly(adapterConfig.isAutodetectBearerOnly()); - deployment.setEnableBasicAuth(adapterConfig.isEnableBasicAuth()); - deployment.setAlwaysRefreshToken(adapterConfig.isAlwaysRefreshToken()); - deployment.setRegisterNodeAtStartup(adapterConfig.isRegisterNodeAtStartup()); - deployment.setRegisterNodePeriod(adapterConfig.getRegisterNodePeriod()); - deployment.setTokenMinimumTimeToLive(adapterConfig.getTokenMinimumTimeToLive()); - deployment.setMinTimeBetweenJwksRequests(adapterConfig.getMinTimeBetweenJwksRequests()); - deployment.setPublicKeyCacheTtl(adapterConfig.getPublicKeyCacheTtl()); - deployment.setIgnoreOAuthQueryParameter(adapterConfig.isIgnoreOAuthQueryParameter()); - deployment.setRewriteRedirectRules(adapterConfig.getRedirectRewriteRules()); - deployment.setVerifyTokenAudience(adapterConfig.isVerifyTokenAudience()); - - if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) { - throw new IllegalArgumentException("For bearer auth, you must set the realm-public-key or auth-server-url"); - } - if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) { - throw new RuntimeException("You must specify auth-server-url"); - } - deployment.setClient(createHttpClientProducer(adapterConfig)); - deployment.setAuthServerBaseUrl(adapterConfig); - if (adapterConfig.getTurnOffChangeSessionIdOnLogin() != null) { - deployment.setTurnOffChangeSessionIdOnLogin(adapterConfig.getTurnOffChangeSessionIdOnLogin()); - } - - final PolicyEnforcerConfig policyEnforcerConfig = adapterConfig.getPolicyEnforcerConfig(); - - if (policyEnforcerConfig != null) { - deployment.setPolicyEnforcer(new Callable() { - PolicyEnforcer policyEnforcer; - @Override - public PolicyEnforcer call() { - if (policyEnforcer == null) { - synchronized (deployment) { - if (policyEnforcer == null) { - policyEnforcer = PolicyEnforcer.builder() - .authServerUrl(adapterConfig.getAuthServerUrl()) - .realm(adapterConfig.getRealm()) - .clientId(adapterConfig.getResource()) - .bearerOnly(adapterConfig.isBearerOnly()) - .credentialProvider(deployment.getClientAuthenticator()) - .enforcerConfig(policyEnforcerConfig) - .httpClient(deployment.getClient()).build(); - } - } - } - return policyEnforcer; - } - }); - } - - return deployment; - } - - private Callable createHttpClientProducer(final AdapterConfig adapterConfig) { - return new Callable() { - private HttpClient client; - @Override - public HttpClient call() { - if (client == null) { - synchronized (deployment) { - if (client == null) { - client = new HttpClientBuilder().build(adapterConfig); - } - } - } - return client; - } - }; - } - - public static KeycloakDeployment build(InputStream is) { - CryptoIntegration.init(KeycloakDeploymentBuilder.class.getClassLoader()); - AdapterConfig adapterConfig = loadAdapterConfig(is); - return new KeycloakDeploymentBuilder().internalBuild(adapterConfig); - } - - public static AdapterConfig loadAdapterConfig(InputStream is) { - ObjectMapper mapper = new ObjectMapper(new SystemPropertiesJsonParserFactory()); - mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); - AdapterConfig adapterConfig; - try { - adapterConfig = mapper.readValue(is, AdapterConfig.class); - } catch (IOException e) { - throw new RuntimeException(e); - } - return adapterConfig; - } - - - public static KeycloakDeployment build(AdapterConfig adapterConfig) { - CryptoIntegration.init(KeycloakDeploymentBuilder.class.getClassLoader()); - return new KeycloakDeploymentBuilder().internalBuild(adapterConfig); - } - - -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/OIDCHttpFacade.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/OIDCHttpFacade.java deleted file mode 100755 index 6b9aa78fe7..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/OIDCHttpFacade.java +++ /dev/null @@ -1,32 +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.adapters; - -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.spi.HttpFacade; - -/** - * Bridge between core adapter and HTTP Engine - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -public interface OIDCHttpFacade extends HttpFacade { - - KeycloakSecurityContext getSecurityContext(); -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java deleted file mode 100755 index 9a91f1225e..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java +++ /dev/null @@ -1,190 +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.adapters; - -import org.jboss.logging.Logger; -import org.keycloak.AuthorizationContext; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.rotation.AdapterTokenVerifier; -import org.keycloak.common.VerificationException; -import org.keycloak.common.util.Time; -import org.keycloak.representations.AccessToken; -import org.keycloak.representations.AccessTokenResponse; -import org.keycloak.representations.IDToken; - -import java.io.IOException; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext { - - protected static Logger log = Logger.getLogger(RefreshableKeycloakSecurityContext.class); - - protected transient KeycloakDeployment deployment; - protected String refreshToken; - - public RefreshableKeycloakSecurityContext() { - } - - public RefreshableKeycloakSecurityContext(KeycloakDeployment deployment, String tokenString, AccessToken token, String idTokenString, IDToken idToken, String refreshToken) { - super(tokenString, token, idTokenString, idToken); - this.deployment = deployment; - this.refreshToken = refreshToken; - } - - @Override - public AccessToken getToken() { - refreshExpiredToken(true); - return super.getToken(); - } - - @Override - public String getTokenString() { - refreshExpiredToken(true); - return super.getTokenString(); - } - - @Override - public IDToken getIdToken() { - refreshExpiredToken(true); - return super.getIdToken(); - } - - @Override - public String getIdTokenString() { - refreshExpiredToken(true); - return super.getIdTokenString(); - } - - public String getRefreshToken() { - return refreshToken; - } - - public void logout(KeycloakDeployment deployment) { - try { - ServerRequest.invokeLogout(deployment, refreshToken); - } catch (Exception e) { - log.error("failed to invoke remote logout", e); - } - } - - public boolean isActive() { - return token != null && this.token.isActive() && deployment!=null && this.token.getIat() >= deployment.getNotBefore(); - } - - public boolean isTokenTimeToLiveSufficient(AccessToken token) { - return token != null && (token.getExp() - this.deployment.getTokenMinimumTimeToLive()) > Time.currentTime(); - } - - public KeycloakDeployment getDeployment() { - return deployment; - } - - public void setCurrentRequestInfo(KeycloakDeployment deployment) { - this.deployment = deployment; - } - - /** - * @param checkActive if true, then we won't send refresh request if current accessToken is still active. - * @return true if accessToken is active or was successfully refreshed - */ - public boolean refreshExpiredToken(boolean checkActive) { - if (checkActive) { - if (log.isTraceEnabled()) { - log.trace("checking whether to refresh."); - } - if (isActive() && isTokenTimeToLiveSufficient(this.token)) return true; - } - - if (this.deployment == null || refreshToken == null) return false; // Might be serialized in HttpSession? - - if (!this.getRealm().equals(this.deployment.getRealm())) { - // this should not happen, but let's check it anyway - return false; - } - - if (log.isTraceEnabled()) { - log.trace("Doing refresh"); - } - - // block requests if the refresh token herein stored is already being used to refresh the token so that subsequent requests - // can use the last refresh token issued by the server. Note that this will only work for deployments using the session store - // and, when running in a cluster, sticky sessions must be used. - // - synchronized (this) { - if (checkActive) { - log.trace("Checking whether token has been refreshed in another thread already."); - if (isActive() && isTokenTimeToLiveSufficient(this.token)) return true; - } - AccessTokenResponse response; - try { - response = ServerRequest.invokeRefresh(deployment, refreshToken); - } catch (IOException e) { - log.error("Refresh token failure", e); - return false; - } catch (ServerRequest.HttpFailure httpFailure) { - final Logger.Level logLevel = httpFailure.getError().contains("Refresh token expired") ? Logger.Level.WARN : Logger.Level.ERROR; - log.log(logLevel, "Refresh token failure status: " + httpFailure.getStatus() + " " + httpFailure.getError()); - return false; - } - if (log.isTraceEnabled()) { - log.trace("received refresh response"); - } - String tokenString = response.getToken(); - AccessToken token = null; - IDToken idToken = null; - try { - AdapterTokenVerifier.VerifiedTokens tokens = AdapterTokenVerifier.verifyTokens(tokenString, response.getIdToken(), deployment); - token = tokens.getAccessToken(); - idToken = tokens.getIdToken(); - log.debug("Token Verification succeeded!"); - } catch (VerificationException e) { - log.error("failed verification of token"); - return false; - } - // If the TTL is greater-or-equal to the expire time on the refreshed token, have to abort or go into an infinite refresh loop - if (!isTokenTimeToLiveSufficient(token)) { - log.error("failed to refresh the token with a longer time-to-live than the minimum"); - return false; - } - if (response.getNotBeforePolicy() > deployment.getNotBefore()) { - deployment.updateNotBefore(response.getNotBeforePolicy()); - } - if (idToken != null) { - this.idToken = idToken; - this.idTokenString = response.getIdToken(); - } - this.token = token; - if (response.getRefreshToken() != null) { - if (log.isTraceEnabled()) { - log.trace("Setup new refresh token to the security context"); - } - this.refreshToken = response.getRefreshToken(); - } - this.tokenString = tokenString; - } - - return true; - } - - public void setAuthorizationContext(AuthorizationContext authorizationContext) { - this.authorizationContext = authorizationContext; - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/ServerRequest.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/ServerRequest.java deleted file mode 100755 index 24f7aa73f9..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/ServerRequest.java +++ /dev/null @@ -1,299 +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.adapters; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.message.BasicNameValuePair; -import org.keycloak.OAuth2Constants; -import org.keycloak.common.util.HostUtils; -import org.keycloak.common.util.KeycloakUriBuilder; -import org.keycloak.common.util.StreamUtil; -import org.keycloak.constants.AdapterConstants; -import org.keycloak.representations.AccessTokenResponse; -import org.keycloak.util.JsonSerialization; - -import org.jboss.logging.Logger; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class ServerRequest { - - private static Logger logger = Logger.getLogger(ServerRequest.class); - - public static class HttpFailure extends Exception { - private int status; - private String error; - - public HttpFailure(int status, String error) { - this.status = status; - this.error = error; - } - - public int getStatus() { - return status; - } - - public String getError() { - return error; - } - } - - public static void invokeLogout(KeycloakDeployment deployment, String refreshToken) throws IOException, HttpFailure { - HttpClient client = deployment.getClient(); - URI uri = deployment.getLogoutUrl().clone().build(); - List formparams = new ArrayList<>(); - - formparams.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken)); - HttpPost post = new HttpPost(uri); - AdapterUtils.setClientCredentials(deployment, post, formparams); - - UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8"); - post.setEntity(form); - HttpResponse response = client.execute(post); - int status = response.getStatusLine().getStatusCode(); - HttpEntity entity = response.getEntity(); - if (status != 204) { - error(status, entity); - } - if (entity == null) { - return; - } - InputStream is = entity.getContent(); - if (is != null) is.close(); - } - - public static AccessTokenResponse invokeAccessCodeToToken(KeycloakDeployment deployment, String code, String redirectUri, String sessionId) throws IOException, HttpFailure { - List formparams = new ArrayList<>(); - redirectUri = stripOauthParametersFromRedirect(redirectUri); - formparams.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, "authorization_code")); - formparams.add(new BasicNameValuePair(OAuth2Constants.CODE, code)); - formparams.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri)); - if (sessionId != null) { - formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, sessionId)); - formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, HostUtils.getHostName())); - } - - HttpPost post = new HttpPost(deployment.getTokenUrl()); - AdapterUtils.setClientCredentials(deployment, post, formparams); - - UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8"); - post.setEntity(form); - HttpResponse response = deployment.getClient().execute(post); - int status = response.getStatusLine().getStatusCode(); - HttpEntity entity = response.getEntity(); - if (status != 200) { - error(status, entity); - } - if (entity == null) { - throw new HttpFailure(status, null); - } - InputStream is = entity.getContent(); - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int c; - while ((c = is.read()) != -1) { - os.write(c); - } - byte[] bytes = os.toByteArray(); - String json = new String(bytes); - try { - return JsonSerialization.readValue(json, AccessTokenResponse.class); - } catch (IOException e) { - throw new IOException(json, e); - } - } finally { - try { - is.close(); - } catch (IOException ignored) { - - } - } - } - - // https://tools.ietf.org/html/rfc7636#section-4 - public static AccessTokenResponse invokeAccessCodeToToken(KeycloakDeployment deployment, String code, String redirectUri, String sessionId, String codeVerifier) throws IOException, HttpFailure { - List formparams = new ArrayList<>(); - redirectUri = stripOauthParametersFromRedirect(redirectUri); - formparams.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, "authorization_code")); - formparams.add(new BasicNameValuePair(OAuth2Constants.CODE, code)); - formparams.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri)); - if (sessionId != null) { - formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, sessionId)); - formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, HostUtils.getHostName())); - } - // https://tools.ietf.org/html/rfc7636#section-4 - if (codeVerifier != null) { - logger.debugf("add to POST parameters of Token Request, codeVerifier = %s", codeVerifier); - formparams.add(new BasicNameValuePair(OAuth2Constants.CODE_VERIFIER, codeVerifier)); - } else { - logger.debug("add to POST parameters of Token Request without codeVerifier"); - } - - HttpPost post = new HttpPost(deployment.getTokenUrl()); - AdapterUtils.setClientCredentials(deployment, post, formparams); - - UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8"); - post.setEntity(form); - HttpResponse response = deployment.getClient().execute(post); - int status = response.getStatusLine().getStatusCode(); - HttpEntity entity = response.getEntity(); - if (status != 200) { - error(status, entity); - } - if (entity == null) { - throw new HttpFailure(status, null); - } - InputStream is = entity.getContent(); - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int c; - while ((c = is.read()) != -1) { - os.write(c); - } - byte[] bytes = os.toByteArray(); - String json = new String(bytes); - try { - return JsonSerialization.readValue(json, AccessTokenResponse.class); - } catch (IOException e) { - throw new IOException(json, e); - } - } finally { - try { - is.close(); - } catch (IOException ignored) { - - } - } - } - - public static AccessTokenResponse invokeRefresh(KeycloakDeployment deployment, String refreshToken) throws IOException, HttpFailure { - List formparams = new ArrayList(); - formparams.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.REFRESH_TOKEN)); - formparams.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken)); - - HttpPost post = new HttpPost(deployment.getTokenUrl()); - AdapterUtils.setClientCredentials(deployment, post, formparams); - - UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8"); - post.setEntity(form); - HttpResponse response = deployment.getClient().execute(post); - int status = response.getStatusLine().getStatusCode(); - HttpEntity entity = response.getEntity(); - if (status != 200) { - error(status, entity); - } - if (entity == null) { - throw new HttpFailure(status, null); - } - InputStream is = entity.getContent(); - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int c; - while ((c = is.read()) != -1) { - os.write(c); - } - byte[] bytes = os.toByteArray(); - String json = new String(bytes); - try { - return JsonSerialization.readValue(json, AccessTokenResponse.class); - } catch (IOException e) { - throw new IOException(json, e); - } - } finally { - try { - is.close(); - } catch (IOException ignored) { - - } - } - } - - public static void invokeRegisterNode(KeycloakDeployment deployment, String host) throws HttpFailure, IOException { - String registerNodeUrl = deployment.getRegisterNodeUrl(); - invokeClientManagementRequest(deployment, host, registerNodeUrl); - } - - public static void invokeUnregisterNode(KeycloakDeployment deployment, String host) throws HttpFailure, IOException { - String unregisterNodeUrl = deployment.getUnregisterNodeUrl(); - invokeClientManagementRequest(deployment, host, unregisterNodeUrl); - } - - public static void invokeClientManagementRequest(KeycloakDeployment deployment, String host, String endpointUrl) throws HttpFailure, IOException { - if (endpointUrl == null) { - throw new IOException("You need to configure URI for register/unregister node for application " + deployment.getResourceName()); - } - - List formparams = new ArrayList<>(); - formparams.add(new BasicNameValuePair(AdapterConstants.CLIENT_CLUSTER_HOST, host)); - - HttpPost post = new HttpPost(endpointUrl); - AdapterUtils.setClientCredentials(deployment, post, formparams); - - UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8"); - post.setEntity(form); - HttpResponse response = deployment.getClient().execute(post); - int status = response.getStatusLine().getStatusCode(); - if (status != 204) { - HttpEntity entity = response.getEntity(); - error(status, entity); - } - } - - public static void error(int status, HttpEntity entity) throws HttpFailure, IOException { - String body = null; - if (entity != null) { - InputStream is = entity.getContent(); - try { - body = StreamUtil.readString(is); - } catch (IOException e) { - - } finally { - try { - is.close(); - } catch (IOException ignored) { - - } - } - } - throw new HttpFailure(status, body); - } - - protected static String stripOauthParametersFromRedirect(String uri) { - KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(uri) - .replaceQueryParam(OAuth2Constants.CODE, null) - .replaceQueryParam(OAuth2Constants.STATE, null) - .replaceQueryParam(OAuth2Constants.ISSUER, null); - return builder.buildAsString(); - } - - -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/SniSSLSocketFactory.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/SniSSLSocketFactory.java deleted file mode 100644 index 89b952e7e9..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/SniSSLSocketFactory.java +++ /dev/null @@ -1,156 +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.adapters; - -import org.apache.http.HttpHost; -import org.apache.http.conn.scheme.HostNameResolver; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.protocol.HttpContext; -import org.keycloak.common.util.Environment; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.security.AccessController; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Marko Strukelj - */ -public class SniSSLSocketFactory extends SSLSocketFactory { - - private static final Logger LOG = Logger.getLogger(SniSSLSocketFactory.class.getName()); - private static final AtomicBoolean skipSNIApplication = new AtomicBoolean(false); - - public SniSSLSocketFactory(String algorithm, KeyStore keystore, String keyPassword, KeyStore truststore, SecureRandom random, HostNameResolver nameResolver) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(algorithm, keystore, keyPassword, truststore, random, nameResolver); - } - - public SniSSLSocketFactory(String algorithm, KeyStore keystore, String keyPassword, KeyStore truststore, SecureRandom random, TrustStrategy trustStrategy, X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(algorithm, keystore, keyPassword, truststore, random, trustStrategy, hostnameVerifier); - } - - public SniSSLSocketFactory(String algorithm, KeyStore keystore, String keyPassword, KeyStore truststore, SecureRandom random, X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(algorithm, keystore, keyPassword, truststore, random, hostnameVerifier); - } - - public SniSSLSocketFactory(KeyStore keystore, String keystorePassword, KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(keystore, keystorePassword, truststore); - } - - public SniSSLSocketFactory(KeyStore keystore, String keystorePassword) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(keystore, keystorePassword); - } - - public SniSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(truststore); - } - - public SniSSLSocketFactory(TrustStrategy trustStrategy, X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(trustStrategy, hostnameVerifier); - } - - public SniSSLSocketFactory(TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - super(trustStrategy); - } - - public SniSSLSocketFactory(SSLContext sslContext) { - super(sslContext); - } - - public SniSSLSocketFactory(SSLContext sslContext, HostNameResolver nameResolver) { - super(sslContext, nameResolver); - } - - public SniSSLSocketFactory(SSLContext sslContext, X509HostnameVerifier hostnameVerifier) { - super(sslContext, hostnameVerifier); - } - - public SniSSLSocketFactory(SSLContext sslContext, String[] supportedProtocols, String[] supportedCipherSuites, X509HostnameVerifier hostnameVerifier) { - super(sslContext, supportedProtocols, supportedCipherSuites, hostnameVerifier); - } - - public SniSSLSocketFactory(javax.net.ssl.SSLSocketFactory socketfactory, X509HostnameVerifier hostnameVerifier) { - super(socketfactory, hostnameVerifier); - } - - public SniSSLSocketFactory(javax.net.ssl.SSLSocketFactory socketfactory, String[] supportedProtocols, String[] supportedCipherSuites, X509HostnameVerifier hostnameVerifier) { - super(socketfactory, supportedProtocols, supportedCipherSuites, hostnameVerifier); - } - - @Override - public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context) throws IOException { - return super.connectSocket(connectTimeout, applySNI(socket, host.getHostName()), host, remoteAddress, localAddress, context); - } - - @Override - public Socket createLayeredSocket(Socket socket, String target, int port, HttpContext context) throws IOException { - return super.createLayeredSocket(applySNI(socket, target), target, port, context); - } - - private Socket applySNI(final Socket socket, String hostname) { - if (skipSNIApplication.get()) { - LOG.log(Level.FINE, "Skipping application of SNI because JDK is missing setHost() method."); - return socket; - } - - if (socket instanceof SSLSocket) { - try { - Method setHostMethod = AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Method run() throws NoSuchMethodException { - return socket.getClass().getMethod("setHost", String.class); - } - }); - - setHostMethod.invoke(socket, hostname); - LOG.log(Level.FINE, "Applied SNI to socket for host {0}", hostname); - } catch (PrivilegedActionException e) { - if (e.getCause() instanceof NoSuchMethodException) { - // For IBM java there is no method with name setHost(), however we don't need to applySNI - // because IBM java is doing it automatically, so we can set lower level of this message - // See: KEYCLOAK-6817 - Level logLevel = Environment.IS_IBM_JAVA ? Level.FINE : Level.WARNING; - LOG.log(logLevel, "Failed to apply SNI to SSLSocket", e); - skipSNIApplication.set(true); - } else { - LOG.log(Level.WARNING, "Failed to apply SNI to SSLSocket", e); - } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - LOG.log(Level.WARNING, "Failed to apply SNI to SSLSocket", e); - } - } - return socket; - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/pep/HttpAuthzRequest.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/pep/HttpAuthzRequest.java deleted file mode 100644 index bcc216485c..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/pep/HttpAuthzRequest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2023 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.adapters.pep; - -import java.io.InputStream; -import java.util.List; - -import org.keycloak.adapters.OIDCHttpFacade; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.authorization.TokenPrincipal; -import org.keycloak.adapters.authorization.spi.HttpRequest; -import org.keycloak.adapters.spi.HttpFacade.Cookie; -import org.keycloak.representations.AccessToken; - -/** - * @author Pedro Igor - */ -public class HttpAuthzRequest implements HttpRequest { - - private final TokenPrincipal tokenPrincipal; - private final OIDCHttpFacade oidcFacade; - - public HttpAuthzRequest(OIDCHttpFacade oidcFacade) { - this.oidcFacade = oidcFacade; - tokenPrincipal = new TokenPrincipal() { - @Override - public String getRawToken() { - KeycloakSecurityContext securityContext = oidcFacade.getSecurityContext(); - - if (securityContext == null) { - return null; - } - - return oidcFacade.getSecurityContext().getTokenString(); - } - - @Override - public AccessToken getToken() { - KeycloakSecurityContext securityContext = oidcFacade.getSecurityContext(); - - if (securityContext == null) { - return null; - } - - return securityContext.getToken(); - } - }; - } - - @Override - public String getRelativePath() { - return oidcFacade.getRequest().getRelativePath(); - } - - @Override - public String getMethod() { - return oidcFacade.getRequest().getMethod(); - } - - @Override - public String getURI() { - return oidcFacade.getRequest().getURI(); - } - - @Override - public List getHeaders(String name) { - return oidcFacade.getRequest().getHeaders(name); - } - - @Override - public String getFirstParam(String name) { - String queryParamValue = oidcFacade.getRequest().getQueryParamValue(name); - - if (queryParamValue != null) { - return queryParamValue; - } - - return oidcFacade.getRequest().getFirstParam(name); - } - - @Override - public String getCookieValue(String name) { - Cookie cookie = oidcFacade.getRequest().getCookie(name); - - if (cookie == null) { - return null; - } - - return cookie.getValue(); - } - - @Override - public String getRemoteAddr() { - return oidcFacade.getRequest().getRemoteAddr(); - } - - @Override - public boolean isSecure() { - return oidcFacade.getRequest().isSecure(); - } - - @Override - public String getHeader(String name) { - return oidcFacade.getRequest().getHeader(name); - } - - @Override - public InputStream getInputStream(boolean buffered) { - return oidcFacade.getRequest().getInputStream(buffered); - } - - @Override - public TokenPrincipal getPrincipal() { - return tokenPrincipal; - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/pep/HttpAuthzResponse.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/pep/HttpAuthzResponse.java deleted file mode 100644 index e14d74bc08..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/pep/HttpAuthzResponse.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 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.adapters.pep; - -import org.keycloak.adapters.OIDCHttpFacade; -import org.keycloak.adapters.authorization.spi.HttpResponse; - -/** - * @author Pedro Igor - */ -public class HttpAuthzResponse implements HttpResponse { - - private OIDCHttpFacade oidcFacade; - - public HttpAuthzResponse(OIDCHttpFacade oidcFacade) { - this.oidcFacade = oidcFacade; - } - - @Override - public void sendError(int statusCode) { - oidcFacade.getResponse().setStatus(statusCode); - } - - @Override - public void sendError(int code, String reason) { - oidcFacade.getResponse().sendError(code, reason); - } - - @Override - public void setHeader(String name, String value) { - oidcFacade.getResponse().setHeader(name, value); - } - -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/AdapterTokenVerifier.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/AdapterTokenVerifier.java deleted file mode 100644 index 80c20a0e96..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/AdapterTokenVerifier.java +++ /dev/null @@ -1,150 +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.adapters.rotation; - -import org.keycloak.adapters.KeycloakDeployment; -import org.jboss.logging.Logger; -import org.keycloak.TokenVerifier; -import org.keycloak.common.VerificationException; -import org.keycloak.representations.AccessToken; -import org.keycloak.representations.IDToken; -import org.keycloak.representations.JsonWebToken; - -import java.security.PublicKey; - -/** - * @author Marek Posolda - */ -public class AdapterTokenVerifier { - - private static final Logger log = Logger.getLogger(AdapterTokenVerifier.class); - - - /** - * Verifies bearer token. Typically called when bearer token (access token) is sent to the service, which wants to verify it. Hence it also checks the audience in the token. - * - * @param tokenString - * @param deployment - * @return - * @throws VerificationException - */ - public static AccessToken verifyToken(String tokenString, KeycloakDeployment deployment) throws VerificationException { - TokenVerifier tokenVerifier = createVerifier(tokenString, deployment, true, AccessToken.class); - - // Verify audience of bearer-token - if (deployment.isVerifyTokenAudience()) { - tokenVerifier.audience(deployment.getResourceName()); - } - - return tokenVerifier.verify().getToken(); - } - - - /** - * Verify access token and ID token. Typically called after successful tokenResponse is received from Keycloak - * - * @param accessTokenString - * @param idTokenString - * @param deployment - * @return verified and parsed accessToken and idToken - * @throws VerificationException - */ - public static VerifiedTokens verifyTokens(String accessTokenString, String idTokenString, KeycloakDeployment deployment) throws VerificationException { - // Adapters currently do most of the checks including signature etc on the access token - TokenVerifier tokenVerifier = createVerifier(accessTokenString, deployment, true, AccessToken.class); - AccessToken accessToken = tokenVerifier.verify().getToken(); - - if (idTokenString != null) { - // Don't verify signature again on IDToken - IDToken idToken = TokenVerifier.create(idTokenString, IDToken.class).getToken(); - TokenVerifier idTokenVerifier = TokenVerifier.createWithoutSignature(idToken); - - // Always verify audience and azp on IDToken - idTokenVerifier.audience(deployment.getResourceName()); - idTokenVerifier.issuedFor(deployment.getResourceName()); - - idTokenVerifier.verify(); - return new VerifiedTokens(accessToken, idToken); - } else { - return new VerifiedTokens(accessToken, null); - } - } - - - /** - * Creates verifier, initializes it from the KeycloakDeployment and adds the publicKey and some default basic checks (activeness and tokenType). Useful if caller wants to add/remove/update - * some checks - * - * @param tokenString - * @param deployment - * @param withDefaultChecks - * @param tokenClass - * @param - * @return tokenVerifier - * @throws VerificationException - */ - public static TokenVerifier createVerifier(String tokenString, KeycloakDeployment deployment, boolean withDefaultChecks, Class tokenClass) throws VerificationException { - TokenVerifier tokenVerifier = TokenVerifier.create(tokenString, tokenClass); - - if (withDefaultChecks) { - tokenVerifier - .withDefaultChecks() - .realmUrl(deployment.getRealmInfoUrl()); - } - - String kid = tokenVerifier.getHeader().getKeyId(); - PublicKey publicKey = getPublicKey(kid, deployment); - tokenVerifier.publicKey(publicKey); - - return tokenVerifier; - } - - - private static PublicKey getPublicKey(String kid, KeycloakDeployment deployment) throws VerificationException { - PublicKeyLocator pkLocator = deployment.getPublicKeyLocator(); - - PublicKey publicKey = pkLocator.getPublicKey(kid, deployment); - if (publicKey == null) { - log.errorf("Didn't find publicKey for kid: %s", kid); - throw new VerificationException("Didn't find publicKey for specified kid"); - } - - return publicKey; - } - - - public static class VerifiedTokens { - - private final AccessToken accessToken; - private final IDToken idToken; - - public VerifiedTokens(AccessToken accessToken, IDToken idToken) { - this.accessToken = accessToken; - this.idToken = idToken; - } - - - public AccessToken getAccessToken() { - return accessToken; - } - - public IDToken getIdToken() { - return idToken; - } - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java deleted file mode 100644 index feb6e48449..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java +++ /dev/null @@ -1,44 +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.adapters.rotation; - -import org.keycloak.adapters.KeycloakDeployment; - -import java.security.PublicKey; - -/** - * @author Marek Posolda - */ -public class HardcodedPublicKeyLocator implements PublicKeyLocator { - - private PublicKey publicKey; - - public HardcodedPublicKeyLocator(PublicKey publicKey) { - this.publicKey = publicKey; - } - - @Override - public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) { - return publicKey; - } - - @Override - public void reset(KeycloakDeployment deployment) { - - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java deleted file mode 100644 index b94ed2787f..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java +++ /dev/null @@ -1,116 +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.adapters.rotation; - -import org.apache.http.client.methods.HttpGet; -import org.jboss.logging.Logger; -import org.keycloak.adapters.HttpAdapterUtils; -import org.keycloak.adapters.HttpClientAdapterException; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.common.util.Time; -import org.keycloak.jose.jwk.JSONWebKeySet; -import org.keycloak.jose.jwk.JWK; -import org.keycloak.util.JWKSUtils; - -import java.security.PublicKey; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * When needed, publicKeys are downloaded by sending request to realm's jwks_url - * - * @author Marek Posolda - */ -public class JWKPublicKeyLocator implements PublicKeyLocator { - - private static final Logger log = Logger.getLogger(JWKPublicKeyLocator.class); - - private Map currentKeys = new ConcurrentHashMap<>(); - - private volatile int lastRequestTime = 0; - - @Override - public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) { - int minTimeBetweenRequests = deployment.getMinTimeBetweenJwksRequests(); - int publicKeyCacheTtl = deployment.getPublicKeyCacheTtl(); - int currentTime = Time.currentTime(); - - // Check if key is in cache. - PublicKey publicKey = lookupCachedKey(publicKeyCacheTtl, currentTime, kid); - if (publicKey != null) { - return publicKey; - } - - // Check if we are allowed to send request - synchronized (this) { - currentTime = Time.currentTime(); - if (currentTime > lastRequestTime + minTimeBetweenRequests) { - sendRequest(deployment); - lastRequestTime = currentTime; - } else { - log.debugf("Won't send request to realm jwks url. Last request time was %d. Current time is %d.", lastRequestTime, currentTime); - } - - return lookupCachedKey(publicKeyCacheTtl, currentTime, kid); - } - } - - - @Override - public void reset(KeycloakDeployment deployment) { - synchronized (this) { - sendRequest(deployment); - lastRequestTime = Time.currentTime(); - log.debugf("Reset time offset to %d.", lastRequestTime); - } - } - - - private PublicKey lookupCachedKey(int publicKeyCacheTtl, int currentTime, String kid) { - if (lastRequestTime + publicKeyCacheTtl > currentTime && kid != null) { - return currentKeys.get(kid); - } else { - return null; - } - } - - - private void sendRequest(KeycloakDeployment deployment) { - if (log.isTraceEnabled()) { - log.trace("Going to send request to retrieve new set of realm public keys for client " + deployment.getResourceName()); - } - - HttpGet getMethod = new HttpGet(deployment.getJwksUrl()); - try { - JSONWebKeySet jwks = HttpAdapterUtils.sendJsonHttpRequest(deployment, getMethod, JSONWebKeySet.class); - - Map publicKeys = JWKSUtils.getKeysForUse(jwks, JWK.Use.SIG); - - if (log.isDebugEnabled()) { - log.debug("Realm public keys successfully retrieved for client " + deployment.getResourceName() + ". New kids: " + publicKeys.keySet().toString()); - } - - // Update current keys - currentKeys.clear(); - currentKeys.putAll(publicKeys); - - } catch (HttpClientAdapterException e) { - log.error("Error when sending request to retrieve realm keys", e); - } - } -} diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java deleted file mode 100644 index ca0e7c6a85..0000000000 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java +++ /dev/null @@ -1,43 +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.adapters.rotation; - -import org.keycloak.adapters.KeycloakDeployment; - -import java.security.PublicKey; - -/** - * @author Marek Posolda - */ -public interface PublicKeyLocator { - - /** - * @param kid - * @param deployment - * @return publicKey, which should be used for verify signature on given "input" - */ - PublicKey getPublicKey(String kid, KeycloakDeployment deployment); - - /** - * Reset the state of locator (eg. clear the cached keys) - * - * @param deployment - */ - void reset(KeycloakDeployment deployment); - -}