From 44ce2fb74dd8631eb9fef6abce32b492fc8638e6 Mon Sep 17 00:00:00 2001 From: rmartinc Date: Mon, 27 May 2024 08:38:35 +0200 Subject: [PATCH] Modify authz tests to not depende on adapter-core code Closes #29882 Signed-off-by: rmartinc --- .../testsuite/util/AuthzTestUtils.java | 219 +++++++ .../authz/AuthzClientCredentialsTest.java | 8 +- .../ClaimInformationPointProviderTest.java | 272 ++------- .../authz/admin/EnforcerConfigTest.java | 9 +- .../authz/admin/PolicyEnforcerClaimsTest.java | 380 +++--------- .../authz/admin/PolicyEnforcerTest.java | 553 +++--------------- .../enforcer-bearer-only-with-cip.json | 36 +- .../enforcer-bearer-only.json | 5 +- .../enforcer-config-claims-provider.json | 182 +++--- .../enforcer-config-path-cip.json | 40 +- .../enforcer-config-paths-same-name.json | 96 ++- .../enforcer-disabled-enforce-mode-path.json | 18 +- .../enforcer-disabled-enforce-mode.json | 18 +- .../enforcer-disabled-path-nocache.json | 40 +- .../enforcer-entitlement-claims-test.json | 35 +- .../enforcer-lazyload-with-paths.json | 18 +- .../authorization-test/enforcer-lazyload.json | 6 +- .../enforcer-match-http-verbs-scopes.json | 6 +- .../enforcer-no-lazyload.json | 5 +- .../enforcer-on-deny-redirect.json | 5 +- .../enforcer-paths-use-method-config.json | 34 +- .../authorization-test/enforcer-paths.json | 30 +- .../enforcer-uma-claims-test.json | 38 +- 23 files changed, 702 insertions(+), 1351 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AuthzTestUtils.java diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AuthzTestUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AuthzTestUtils.java new file mode 100644 index 0000000000..d5bfc3f6ba --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AuthzTestUtils.java @@ -0,0 +1,219 @@ +/* + * Copyright 2024 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.util; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import org.keycloak.adapters.authorization.PolicyEnforcer; +import org.keycloak.adapters.authorization.TokenPrincipal; +import org.keycloak.adapters.authorization.spi.HttpRequest; +import org.keycloak.adapters.authorization.spi.HttpResponse; + +/** + * + * @author rmartinc + */ +public class AuthzTestUtils { + + private AuthzTestUtils() { + } + + public static InputStream httpsAwareConfigurationStream(InputStream input) throws IOException { + if (!ServerURLs.AUTH_SERVER_SSL_REQUIRED) { + return input; + } + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (PrintWriter pw = new PrintWriter(out); + Scanner s = new Scanner(input)) { + while (s.hasNextLine()) { + String lineWithReplaces = s.nextLine().replace("http://localhost:8180/auth", + ServerURLs.AUTH_SERVER_SCHEME + "://localhost:" + ServerURLs.AUTH_SERVER_PORT + "/auth"); + pw.println(lineWithReplaces); + } + } + return new ByteArrayInputStream(out.toByteArray()); + } + + public static InputStream getAdapterConfiguration(String fileName) { + try { + return httpsAwareConfigurationStream(AuthzTestUtils.class.getResourceAsStream("/authorization-test/" + fileName)); + } catch (IOException e) { + throw new AssertionError("Could not load keycloak configuration", e); + } + } + + public static PolicyEnforcer createPolicyEnforcer(String resource, boolean bearerOnly) { + try (InputStream is = getAdapterConfiguration(resource)) { + return PolicyEnforcer.builder().enforcerConfig(is).bearerOnly(bearerOnly).build(); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid resource " + resource, e); + } + } + + public static HttpRequest createHttpRequest(String path) { + return createHttpRequest(path, null, null, null, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), null); + } + + public static HttpRequest createHttpRequest(String path, String token) { + return createHttpRequest(path, null, null, token, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), null); + } + + public static HttpRequest createHttpRequest(String path, String token, String method) { + return createHttpRequest(path, null, method, token, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), null); + } + + public static HttpRequest createHttpRequest(String path, String token, Map> parameters) { + return createHttpRequest(path, null, null, token, Collections.emptyMap(), parameters, Collections.emptyMap(), null); + } + + public static HttpRequest createHttpRequest(String path, String method, String token, Map> headers, Map> parameters, InputStream requestBody) { + return createHttpRequest(path, null, method, token, headers, parameters, Collections.emptyMap(), null); + } + + public static HttpRequest createHttpRequest(String path, String relativePath, String method, String token, Map> headers, Map> parameters, Map cookies, InputStream requestBody) { + return new HttpRequest() { + + private InputStream inputStream; + + @Override + public String getRelativePath() { + return relativePath != null? relativePath : path; + } + + @Override + public String getMethod() { + return method == null ? "GET" : method; + } + + @Override + public String getURI() { + return path; + } + + @Override + public List getHeaders(String name) { + return headers.getOrDefault(name, Collections.emptyList()); + } + + @Override + public String getFirstParam(String name) { + List values = parameters.getOrDefault(name, Collections.emptyList()); + return values.isEmpty()? null : values.iterator().next(); + } + + @Override + public String getCookieValue(String name) { + return cookies.get(name); + } + + @Override + public String getRemoteAddr() { + return "user-remote-addr"; + } + + @Override + public boolean isSecure() { + return true; + } + + @Override + public String getHeader(String name) { + List headers = getHeaders(name); + return headers.isEmpty()? null : headers.iterator().next(); + } + + @Override + public InputStream getInputStream(boolean buffered) { + if (requestBody == null) { + return new ByteArrayInputStream(new byte[] {}); + } + + if (inputStream != null) { + return inputStream; + } + + if (buffered) { + return inputStream = new BufferedInputStream(requestBody); + } + + return requestBody; + } + + @Override + public TokenPrincipal getPrincipal() { + return () -> token; + } + }; + } + + public static class TestResponse implements HttpResponse { + + private final Map> headers; + private int status; + + public TestResponse() { + this.headers = new HashMap<>(); + } + + public TestResponse(Map> headers) { + this.headers = headers; + } + + public int getStatus() { + return status; + } + + @Override + public void setHeader(String name, String value) { + headers.put(name, Arrays.asList(value)); + } + + public Map> getHeaders() { + return headers; + } + + @Override + public void sendError(int code) { + status = code; + } + + @Override + public void sendError(int code, String message) { + status = code; + } + + public TestResponse clear() { + this.status = -1; + this.headers.clear(); + return this; + } + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java index 07e53dfaf1..d3b0120da5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java @@ -30,8 +30,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; +import org.keycloak.adapters.authorization.PolicyEnforcer; import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.resource.AuthorizationResource; import org.keycloak.admin.client.resource.ClientResource; @@ -39,7 +38,6 @@ import org.keycloak.admin.client.resource.ClientsResource; import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator; import org.keycloak.authentication.authenticators.client.JWTClientSecretAuthenticator; import org.keycloak.authorization.client.AuthzClient; -import org.keycloak.authorization.client.Configuration; import org.keycloak.authorization.client.resource.ProtectionResource; import org.keycloak.authorization.client.util.HttpResponseException; import org.keycloak.common.util.Time; @@ -348,9 +346,9 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { } private AuthzClient getAuthzClient(String adapterConfig) { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getConfigurationStream(adapterConfig)); + PolicyEnforcer policyEnforcer = PolicyEnforcer.builder().enforcerConfig(getConfigurationStream(adapterConfig)).build(); - return AuthzClient.create(new Configuration(deployment.getAuthServerBaseUrl(), deployment.getRealm(), deployment.getResourceName(), deployment.getResourceCredentials(), deployment.getClient())); + return policyEnforcer.getAuthzClient(); } private InputStream getConfigurationStream(String adapterConfig) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ClaimInformationPointProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ClaimInformationPointProviderTest.java index 029add61c4..71faf82c29 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ClaimInformationPointProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ClaimInformationPointProviderTest.java @@ -22,18 +22,13 @@ import static org.junit.Assert.assertNull; import static org.keycloak.common.Profile.Feature.AUTHORIZATION; import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm; -import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.io.OutputStream; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.security.cert.X509Certificate; - import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -41,29 +36,20 @@ import io.undertow.Undertow; import io.undertow.server.handlers.form.FormData; import io.undertow.server.handlers.form.FormDataParser; import io.undertow.server.handlers.form.FormParserFactory; -import org.apache.http.impl.client.HttpClients; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.pep.HttpAuthzRequest; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; -import org.keycloak.adapters.OIDCHttpFacade; import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProvider; import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory; import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.adapters.spi.AuthenticationError; -import org.keycloak.adapters.spi.HttpFacade.Cookie; -import org.keycloak.adapters.spi.HttpFacade.Request; -import org.keycloak.adapters.spi.HttpFacade.Response; -import org.keycloak.adapters.spi.LogoutError; +import org.keycloak.adapters.authorization.spi.HttpRequest; +import org.keycloak.jose.jws.JWSBuilder; import org.keycloak.representations.AccessToken; -import org.keycloak.representations.IDToken; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.ProfileAssume; +import org.keycloak.testsuite.util.AuthzTestUtils; import org.keycloak.util.JsonSerialization; /** @@ -88,7 +74,7 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { FormDataParser parser = parserFactory.createParser(exchange); FormData formData = parser.parseBlocking(); - if (!"Bearer tokenString".equals(exchange.getRequestHeaders().getFirst("Authorization")) + if (!("Bearer " + accessTokenString()).equals(exchange.getRequestHeaders().getFirst("Authorization")) || !"post".equalsIgnoreCase(exchange.getRequestMethod().toString()) || !"application/x-www-form-urlencoded".equals(exchange.getRequestHeaders().getFirst("Content-Type")) || !exchange.getRequestHeaders().get("header-b").contains("header-b-value1") @@ -105,7 +91,7 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { exchange.setStatusCode(200); } else if (exchange.getRelativePath().equals("/get-claim-information-provider")) { - if (!"Bearer tokenString".equals(exchange.getRequestHeaders().getFirst("Authorization")) + if (!("Bearer " + accessTokenString()).equals(exchange.getRequestHeaders().getFirst("Authorization")) || !"get".equalsIgnoreCase(exchange.getRequestMethod().toString()) || !exchange.getRequestHeaders().get("header-b").contains("header-b-value1") || !exchange.getRequestHeaders().get("header-b").contains("header-b-value2") @@ -154,9 +140,7 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { } private ClaimInformationPointProvider getClaimInformationProviderForPath(String path, String providerName) { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getClass().getResourceAsStream("/authorization-test/enforcer-config-claims-provider.json")); - deployment.setClient(HttpClients.createDefault()); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-config-claims-provider.json", true); Map providers = policyEnforcer.getClaimInformationPointProviderFactories(); PathConfig pathConfig = policyEnforcer.getPaths().get(path); @@ -178,8 +162,8 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { @Test public void testBasicClaimsInformationPoint() { - OIDCHttpFacade httpFacade = createHttpFacade(); - Map> claims = getClaimInformationProviderForPath("/claims-provider", "claims").resolve(new HttpAuthzRequest(httpFacade)); + Map> claims = getClaimInformationProviderForPath("/claims-provider", "claims") + .resolve(createHttpRequest()); assertEquals("parameter-a", claims.get("claim-from-request-parameter").get(0)); assertEquals("header-b", claims.get("claim-from-header").get(0)); @@ -204,9 +188,9 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { ObjectMapper mapper = JsonSerialization.mapper; JsonParser parser = mapper.getFactory().createParser("{\"a\": {\"b\": {\"c\": \"c-value\"}}, \"d\": [\"d-value1\", \"d-value2\"], \"e\": {\"number\": 123}}"); TreeNode treeNode = mapper.readTree(parser); - OIDCHttpFacade httpFacade = createHttpFacade(headers, new ByteArrayInputStream(treeNode.toString().getBytes())); - Map> claims = getClaimInformationProviderForPath("/claims-provider", "claims").resolve(new HttpAuthzRequest(httpFacade)); + Map> claims = getClaimInformationProviderForPath("/claims-provider", "claims").resolve( + createHttpRequest(headers, new ByteArrayInputStream(treeNode.toString().getBytes()))); assertEquals("c-value", claims.get("claim-from-json-body-object").get(0)); assertEquals("d-value2", claims.get("claim-from-json-body-array").get(0)); @@ -244,9 +228,9 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { + "\n" + "}}"); TreeNode treeNode = mapper.readTree(parser); - OIDCHttpFacade httpFacade = createHttpFacade(headers, new ByteArrayInputStream(treeNode.toString().getBytes())); - Map> claims = getClaimInformationProviderForPath("/claims-from-body-json-object", "claims").resolve(new HttpAuthzRequest(httpFacade)); + Map> claims = getClaimInformationProviderForPath("/claims-from-body-json-object", "claims") + .resolve(createHttpRequest(headers, new ByteArrayInputStream(treeNode.toString().getBytes()))); assertEquals(1, claims.size()); assertEquals(2, claims.get("individualRoles").size()); @@ -255,8 +239,8 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { headers.put("Content-Type", Arrays.asList("application/json; charset=utf-8")); - httpFacade = createHttpFacade(headers, new ByteArrayInputStream(treeNode.toString().getBytes())); - claims = getClaimInformationProviderForPath("/claims-from-body-json-object", "claims").resolve(new HttpAuthzRequest(httpFacade)); + claims = getClaimInformationProviderForPath("/claims-from-body-json-object", "claims") + .resolve(createHttpRequest(headers, new ByteArrayInputStream(treeNode.toString().getBytes()))); assertEquals(1, claims.size()); assertEquals(2, claims.get("individualRoles").size()); @@ -266,18 +250,16 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { @Test public void testBodyClaimsInformationPoint() { - OIDCHttpFacade httpFacade = createHttpFacade(new HashMap<>(), new ByteArrayInputStream("raw-body-text".getBytes())); - - Map> claims = getClaimInformationProviderForPath("/claims-provider", "claims").resolve(new HttpAuthzRequest(httpFacade)); + Map> claims = getClaimInformationProviderForPath("/claims-provider", "claims") + .resolve(createHttpRequest(new HashMap<>(), new ByteArrayInputStream("raw-body-text".getBytes()))); assertEquals("raw-body-text", claims.get("claim-from-body").get(0)); } @Test public void testHttpClaimInformationPointProviderWithoutClaims() { - OIDCHttpFacade httpFacade = createHttpFacade(); - - Map> claims = getClaimInformationProviderForPath("/http-get-claim-provider", "http").resolve(new HttpAuthzRequest(httpFacade)); + Map> claims = getClaimInformationProviderForPath("/http-get-claim-provider", "http") + .resolve(createHttpRequest(new HashMap<>(), null)); assertEquals("a-value1", claims.get("a").get(0)); assertEquals("b-value1", claims.get("b").get(0)); @@ -292,9 +274,8 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { @Test public void testHttpClaimInformationPointProviderWithClaims() { - OIDCHttpFacade httpFacade = createHttpFacade(); - - Map> claims = getClaimInformationProviderForPath("/http-post-claim-provider", "http").resolve(new HttpAuthzRequest(httpFacade)); + Map> claims = getClaimInformationProviderForPath("/http-post-claim-provider", "http") + .resolve(createHttpRequest(new HashMap<>(), null)); assertEquals("a-value1", claims.get("claim-a").get(0)); assertEquals("d-value1", claims.get("claim-d").get(0)); @@ -308,208 +289,29 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest { assertNull(claims.get("d")); } - private OIDCHttpFacade createHttpFacade(Map> headers, InputStream requestBody) { - return new OIDCHttpFacade() { - private Request request; - - @Override - public KeycloakSecurityContext getSecurityContext() { - AccessToken token = new AccessToken(); - - token.subject("sub"); - token.setPreferredUsername("username"); - token.getOtherClaims().put("custom_claim", Arrays.asList("param-other-claims-value1", "param-other-claims-value2")); - - IDToken idToken = new IDToken(); - - idToken.subject("sub"); - idToken.setPreferredUsername("username"); - idToken.getOtherClaims().put("custom_claim", Arrays.asList("param-other-claims-value1", "param-other-claims-value2")); - - return new KeycloakSecurityContext("tokenString", token, "idTokenString", idToken); - } - - @Override - public Request getRequest() { - if (request == null) { - request = createHttpRequest(headers, requestBody); - } - return request; - } - - @Override - public Response getResponse() { - return createHttpResponse(); - } - - @Override - public X509Certificate[] getCertificateChain() { - return new X509Certificate[0]; - } - }; + private static HttpRequest createHttpRequest() { + return createHttpRequest(new HashMap<>(), null); } - private OIDCHttpFacade createHttpFacade() { - return createHttpFacade(new HashMap<>(), null); - } - - private Response createHttpResponse() { - return new Response() { - @Override - public void setStatus(int status) { - - } - - @Override - public void addHeader(String name, String value) { - - } - - @Override - public void setHeader(String name, String value) { - - } - - @Override - public void resetCookie(String name, String path) { - - } - - @Override - public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) { - - } - - @Override - public OutputStream getOutputStream() { - return null; - } - - @Override - public void sendError(int code) { - - } - - @Override - public void sendError(int code, String message) { - - } - - @Override - public void end() { - - } - }; - } - - private Request createHttpRequest(Map> headers, InputStream requestBody) { + private static HttpRequest createHttpRequest(Map> headers, InputStream requestBody) { Map> queryParameter = new HashMap<>(); - queryParameter.put("a", Arrays.asList("parameter-a")); - headers.put("b", Arrays.asList("header-b")); + Map cookies = new HashMap<>(); + cookies.put("c", "cookie-c"); + return AuthzTestUtils.createHttpRequest("/app/request-uri", "/request-relative-path", "GET", + accessTokenString(), headers, queryParameter, cookies, requestBody); + } - Map cookies = new HashMap<>(); + private static AccessToken accessToken() { + AccessToken token = new AccessToken(); + token.subject("sub"); + token.setPreferredUsername("username"); + token.getOtherClaims().put("custom_claim", Arrays.asList("param-other-claims-value1", "param-other-claims-value2")); + return token; + } - cookies.put("c", new Cookie("c", "cookie-c", 1, "localhost", "/")); - - return new Request() { - - private InputStream inputStream; - - @Override - public String getMethod() { - return "GET"; - } - - @Override - public String getURI() { - return "/app/request-uri"; - } - - @Override - public String getRelativePath() { - return "/request-relative-path"; - } - - @Override - public boolean isSecure() { - return true; - } - - @Override - public String getFirstParam(String param) { - List values = queryParameter.getOrDefault(param, Collections.emptyList()); - - if (!values.isEmpty()) { - return values.get(0); - } - - return null; - } - - @Override - public String getQueryParamValue(String param) { - return getFirstParam(param); - } - - @Override - public Cookie getCookie(String cookieName) { - return cookies.get(cookieName); - } - - @Override - public String getHeader(String name) { - List headers = getHeaders(name); - - if (!headers.isEmpty()) { - return headers.get(0); - } - - return null; - } - - @Override - public List getHeaders(String name) { - return headers.getOrDefault(name, Collections.emptyList()); - } - - @Override - public InputStream getInputStream() { - return getInputStream(false); - } - - @Override - public InputStream getInputStream(boolean buffer) { - if (requestBody == null) { - return new ByteArrayInputStream(new byte[] {}); - } - - if (inputStream != null) { - return inputStream; - } - - if (buffer) { - return inputStream = new BufferedInputStream(requestBody); - } - - return requestBody; - } - - @Override - public String getRemoteAddr() { - return "user-remote-addr"; - } - - @Override - public void setError(AuthenticationError error) { - - } - - @Override - public void setError(LogoutError error) { - - } - }; + private static String accessTokenString() { + return new JWSBuilder().jsonContent(accessToken()).none(); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/EnforcerConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/EnforcerConfigTest.java index d02fc3e9d0..a352def249 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/EnforcerConfigTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/EnforcerConfigTest.java @@ -18,13 +18,12 @@ package org.keycloak.testsuite.authz.admin; import org.junit.BeforeClass; import org.junit.Test; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; import org.keycloak.adapters.authorization.PolicyEnforcer; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.util.AuthzTestUtils; import java.util.List; import java.util.Map; @@ -55,8 +54,7 @@ public class EnforcerConfigTest extends AbstractKeycloakTest { @Test public void testMultiplePathsWithSameName() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getClass().getResourceAsStream("/authorization-test/enforcer-config-paths-same-name.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-config-paths-same-name.json", true); Map paths = policyEnforcer.getPaths(); assertEquals(1, paths.size()); assertEquals(4, paths.values().iterator().next().getMethods().size()); @@ -64,8 +62,7 @@ public class EnforcerConfigTest extends AbstractKeycloakTest { @Test public void testPathConfigClaimInformationPoint() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getClass().getResourceAsStream("/authorization-test/enforcer-config-path-cip.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-config-path-cip.json", true); Map paths = policyEnforcer.getPaths(); assertEquals(1, paths.size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerClaimsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerClaimsTest.java index a9a0151523..6a2f1e7135 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerClaimsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerClaimsTest.java @@ -22,42 +22,20 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.keycloak.common.Profile.Feature.AUTHORIZATION; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import javax.security.cert.X509Certificate; - import org.junit.BeforeClass; import org.junit.Test; import org.keycloak.AuthorizationContext; -import org.keycloak.KeycloakSecurityContext; import org.keycloak.OAuth2Constants; -import org.keycloak.adapters.pep.HttpAuthzRequest; -import org.keycloak.adapters.pep.HttpAuthzResponse; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; -import org.keycloak.adapters.OIDCHttpFacade; import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.adapters.spi.AuthenticationError; -import org.keycloak.adapters.spi.HttpFacade.Cookie; -import org.keycloak.adapters.spi.HttpFacade.Request; -import org.keycloak.adapters.spi.HttpFacade.Response; -import org.keycloak.adapters.spi.LogoutError; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ClientsResource; import org.keycloak.authorization.client.AuthzClient; -import org.keycloak.jose.jws.JWSInput; -import org.keycloak.jose.jws.JWSInputException; -import org.keycloak.representations.AccessToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.authorization.AuthorizationRequest; @@ -69,6 +47,7 @@ import org.keycloak.representations.idm.authorization.ScopePermissionRepresentat import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.ProfileAssume; +import org.keycloak.testsuite.util.AuthzTestUtils; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; @@ -122,72 +101,72 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { public void testEnforceUMAAccessWithClaimsUsingBearerToken() { initAuthorizationSettings(getClientResource("resource-server-uma-test")); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-uma-claims-test.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-uma-claims-test.json", true); HashMap> headers = new HashMap<>(); HashMap> parameters = new HashMap<>(); parameters.put("withdrawal.amount", Arrays.asList("50")); - AuthzClient authzClient = getAuthzClient("enforcer-uma-claims-test.json"); + AuthzClient authzClient = policyEnforcer.getAuthzClient(); String token = authzClient.obtainAccessToken("marta", "password").getToken(); headers.put("Authorization", Arrays.asList("Bearer " + token)); - OIDCHttpFacade facade = createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null), + testResponse); assertFalse(context.isGranted()); AuthorizationRequest request = new AuthorizationRequest(); - request.setTicket(extractTicket(headers)); + request.setTicket(extractTicket(testResponse.getHeaders())); AuthorizationResponse response = authzClient.authorization("marta", "password").authorize(request); token = response.getToken(); assertNotNull(token); - facade = createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("200")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null), + testResponse.clear()); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("10")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null), + testResponse.clear()); request = new AuthorizationRequest(); - request.setTicket(extractTicket(headers)); + request.setTicket(extractTicket(testResponse.getHeaders())); response = authzClient.authorization("marta", "password").authorize(request); token = response.getToken(); - facade = createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); - request = new AuthorizationRequest(); - - request.setTicket(extractTicket(headers)); - - response = authzClient.authorization("marta", "password").authorize(request); - token = response.getToken(); - - facade = createHttpFacade("/api/bank/account/1/withdrawal", "GET", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "GET", token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); assertEquals(1, context.getPermissions().size()); @@ -200,22 +179,24 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { public void testEnforceEntitlementAccessWithClaimsWithoutBearerToken() { initAuthorizationSettings(getClientResource("resource-server-test")); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-entitlement-claims-test.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-entitlement-claims-test.json", false); HashMap> headers = new HashMap<>(); HashMap> parameters = new HashMap<>(); - AuthzClient authzClient = getAuthzClient("enforcer-entitlement-claims-test.json"); + AuthzClient authzClient = policyEnforcer.getAuthzClient(); String token = authzClient.obtainAccessToken("marta", "password").getToken(); - OIDCHttpFacade facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); assertEquals(1, context.getPermissions().size()); Permission permission = context.getPermissions().get(0); @@ -223,20 +204,23 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { parameters.put("withdrawal.amount", Arrays.asList("200")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("10")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); @@ -249,42 +233,47 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { public void testEnforceEntitlementAccessWithClaimsWithBearerToken() { initAuthorizationSettings(getClientResource("resource-server-test")); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-entitlement-claims-test.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-entitlement-claims-test.json", false); HashMap> headers = new HashMap<>(); HashMap> parameters = new HashMap<>(); - AuthzClient authzClient = getAuthzClient("enforcer-entitlement-claims-test.json"); + AuthzClient authzClient = policyEnforcer.getAuthzClient(); String token = authzClient.obtainAccessToken("marta", "password").getToken(); headers.put("Authorization", Arrays.asList("Bearer " + token)); - OIDCHttpFacade facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("200")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("10")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); } @@ -293,8 +282,7 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { public void testEnforceEntitlementAccessWithClaimsWithBearerTokenFromPublicClient() { initAuthorizationSettings(getClientResource("resource-server-test")); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-entitlement-claims-test.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-entitlement-claims-test.json", false); HashMap> headers = new HashMap<>(); HashMap> parameters = new HashMap<>(); @@ -308,37 +296,43 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { headers.put("Authorization", Arrays.asList("Bearer " + token)); - OIDCHttpFacade facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("200")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertFalse(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("50")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); parameters.put("withdrawal.amount", Arrays.asList("10")); - facade = createHttpFacade("/api/bank/account/1/withdrawal", token, headers, parameters); - context = policyEnforcer.enforce(new HttpAuthzRequest(facade), new HttpAuthzResponse(facade)); + context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null), + testResponse.clear()); assertTrue(context.isGranted()); } - private String extractTicket(HashMap> headers) { + private String extractTicket(Map> headers) { List wwwAuthenticateHeader = headers.get("WWW-Authenticate"); assertNotNull(wwwAuthenticateHeader); @@ -369,14 +363,6 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { } } - private InputStream getAdapterConfiguration(String fileName) { - try { - return httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + fileName)); - } catch (IOException e) { - throw new AssertionError("Could not load keycloak configuration", e); - } - } - private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) { ResourceRepresentation representation = new ResourceRepresentation(); @@ -397,208 +383,4 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { ClientRepresentation representation = clients.findByClientId(name).get(0); return clients.get(representation.getId()); } - - private OIDCHttpFacade createHttpFacade(String path, String method, String token, Map> headers, Map> parameters, InputStream requestBody) { - return new OIDCHttpFacade() { - Request request; - Response response; - - @Override - public KeycloakSecurityContext getSecurityContext() { - AccessToken accessToken; - try { - accessToken = new JWSInput(token).readJsonContent(AccessToken.class); - } catch (JWSInputException cause) { - throw new RuntimeException(cause); - } - return new KeycloakSecurityContext(token, accessToken, null, null); - } - - @Override - public Request getRequest() { - if (request == null) { - request = createHttpRequest(path, method, headers, parameters, requestBody); - } - return request; - } - - @Override - public Response getResponse() { - if (response == null) { - response = createHttpResponse(headers); - } - return response; - } - - @Override - public X509Certificate[] getCertificateChain() { - return new X509Certificate[0]; - } - }; - } - - private OIDCHttpFacade createHttpFacade(String path, String token, Map> headers, Map> parameters) { - return createHttpFacade(path, null, token, headers, parameters, null); - } - - private OIDCHttpFacade createHttpFacade(String path, String method, String token, Map> headers, Map> parameters) { - return createHttpFacade(path, method, token, headers, parameters, null); - } - - private Response createHttpResponse(Map> headers) { - return new Response() { - - private int status; - - @Override - public void setStatus(int status) { - this.status = status; - } - - @Override - public void addHeader(String name, String value) { - setHeader(name, value); - } - - @Override - public void setHeader(String name, String value) { - headers.put(name, Arrays.asList(value)); - } - - @Override - public void resetCookie(String name, String path) { - - } - - @Override - public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) { - - } - - @Override - public OutputStream getOutputStream() { - return null; - } - - @Override - public void sendError(int code) { - - } - - @Override - public void sendError(int code, String message) { - - } - - @Override - public void end() { - - } - }; - } - - private Request createHttpRequest(String path, String method, Map> headers, Map> parameters, InputStream requestBody) { - return new Request() { - - private InputStream inputStream; - - @Override - public String getMethod() { - return method == null ? "GET" : method; - } - - @Override - public String getURI() { - return path; - } - - @Override - public String getRelativePath() { - return path; - } - - @Override - public boolean isSecure() { - return true; - } - - @Override - public String getFirstParam(String param) { - List values = parameters.getOrDefault(param, Collections.emptyList()); - - if (!values.isEmpty()) { - return values.get(0); - } - - return null; - } - - @Override - public String getQueryParamValue(String param) { - return getFirstParam(param); - } - - @Override - public Cookie getCookie(String cookieName) { - return null; - } - - @Override - public String getHeader(String name) { - List headers = getHeaders(name); - - if (!headers.isEmpty()) { - return headers.get(0); - } - - return null; - } - - @Override - public List getHeaders(String name) { - return headers.getOrDefault(name, Collections.emptyList()); - } - - @Override - public InputStream getInputStream() { - return getInputStream(false); - } - - @Override - public InputStream getInputStream(boolean buffer) { - if (requestBody == null) { - return new ByteArrayInputStream(new byte[] {}); - } - - if (inputStream != null) { - return inputStream; - } - - if (buffer) { - return inputStream = new BufferedInputStream(requestBody); - } - - return requestBody; - } - - @Override - public String getRemoteAddr() { - return "user-remote-addr"; - } - - @Override - public void setError(AuthenticationError error) { - - } - - @Override - public void setError(LogoutError error) { - - } - }; - } - - protected AuthzClient getAuthzClient(String fileName) { - return AuthzClient.create(getAdapterConfiguration(fileName)); - } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerTest.java index 1ed681e376..02f16f9e40 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerTest.java @@ -22,54 +22,26 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.keycloak.common.Profile.Feature.AUTHORIZATION; -import javax.security.cert.X509Certificate; -import jakarta.ws.rs.HttpMethod; -import jakarta.ws.rs.core.HttpHeaders; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; import java.util.stream.Collectors; -import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.keycloak.AuthorizationContext; -import org.keycloak.KeycloakSecurityContext; import org.keycloak.OAuth2Constants; -import org.keycloak.adapters.AuthenticatedActionsHandler; -import org.keycloak.adapters.CorsHeaders; -import org.keycloak.adapters.pep.HttpAuthzRequest; -import org.keycloak.adapters.pep.HttpAuthzResponse; -import org.keycloak.adapters.KeycloakDeployment; -import org.keycloak.adapters.KeycloakDeploymentBuilder; -import org.keycloak.adapters.OIDCHttpFacade; -import org.keycloak.adapters.RefreshableKeycloakSecurityContext; import org.keycloak.adapters.authorization.PolicyEnforcer; -import org.keycloak.adapters.spi.AuthenticationError; -import org.keycloak.adapters.spi.HttpFacade.Cookie; -import org.keycloak.adapters.spi.HttpFacade.Request; -import org.keycloak.adapters.spi.HttpFacade.Response; -import org.keycloak.adapters.spi.LogoutError; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ClientsResource; import org.keycloak.admin.client.resource.PermissionsResource; import org.keycloak.admin.client.resource.ResourcesResource; import org.keycloak.authorization.client.AuthzClient; -import org.keycloak.jose.jws.JWSInput; -import org.keycloak.jose.jws.JWSInputException; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.representations.AccessToken; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; @@ -84,6 +56,7 @@ import org.keycloak.representations.idm.authorization.ScopePermissionRepresentat import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.ProfileAssume; +import org.keycloak.testsuite.util.AuthzTestUtils; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; @@ -143,13 +116,13 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { @Test public void testBearerOnlyClientResponse() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only.json", true); + + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea"), testResponse); assertFalse(context.isGranted()); - assertEquals(403, TestResponse.class.cast(httpFacade.getResponse()).getStatus()); + assertEquals(403, testResponse.getStatus()); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -159,27 +132,24 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - httpFacade = createHttpFacade("/api/resourcea", token); - - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), testResponse.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resourceb"); - - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + testResponse = new AuthzTestUtils.TestResponse(); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourceb"), testResponse.clear()); assertFalse(context.isGranted()); - assertEquals(403, TestResponse.class.cast(httpFacade.getResponse()).getStatus()); + assertEquals(403, testResponse.getStatus()); } @Test - public void testPathConfigurationPrecendenceWhenLazyLoadingPaths() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-paths.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + public void testPathConfigurationPrecendenceWhenLazyLoadingPaths() throws IOException { + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-paths.json", false); + + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea"), testResponse); assertFalse(context.isGranted()); - assertEquals(403, TestResponse.class.cast(httpFacade.getResponse()).getStatus()); + assertEquals(403, testResponse.getStatus()); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -189,21 +159,16 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - httpFacade = createHttpFacade("/api/resourcea", token); - - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), testResponse.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/"); - - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/"), testResponse.clear()); assertTrue(context.isGranted()); } @Test public void testResolvingClaimsOnce() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only-with-cip.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only-with-cip.json", true); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -213,17 +178,9 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea", token, new Function() { - AtomicBoolean resolved = new AtomicBoolean(); - - @Override - public String apply(String s) { - Assert.assertTrue(resolved.compareAndSet(false, true)); - return "value-" + s; - } - }); - - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce( + AuthzTestUtils.createHttpRequest("/api/resourcea", token, Collections.singletonMap("claim-a", Collections.singletonList("value-claim-a"))), + new AuthzTestUtils.TestResponse()); Permission permission = context.getPermissions().get(0); Map> claims = permission.getClaims(); @@ -234,8 +191,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { @Test public void testCustomClaimProvider() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only-with-cip.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only-with-cip.json", true); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -245,9 +201,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea", token); - - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), new AuthzTestUtils.TestResponse()); Permission permission = context.getPermissions().get(0); Map> claims = permission.getClaims(); @@ -257,13 +211,12 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { @Test public void testOnDenyRedirectTo() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-on-deny-redirect.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-on-deny-redirect.json", false); + + AuthzTestUtils.TestResponse response = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea"), response); assertFalse(context.isGranted()); - TestResponse response = TestResponse.class.cast(httpFacade.getResponse()); assertEquals(302, response.getStatus()); List location = response.getHeaders().getOrDefault("Location", Collections.emptyList()); assertFalse(location.isEmpty()); @@ -272,50 +225,25 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { @Test public void testNotAuthenticatedDenyUnmapedPath() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/unmmaped"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only.json", true); + + AuthzTestUtils.TestResponse response = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/unmmaped"), response); assertFalse(context.isGranted()); - TestResponse response = TestResponse.class.cast(httpFacade.getResponse()); assertEquals(403, response.getStatus()); } - @Test - public void testPublicEndpointNoBearerAbortRequest() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only.json")); - OIDCHttpFacade httpFacade = createHttpFacade("/api/public"); - AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deployment, httpFacade); - - assertTrue(handler.handledRequest()); - - oauth.realm(REALM_NAME); - oauth.clientId("public-client-test"); - oauth.doLogin("marta", "password"); - - String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); - OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); - String token = response.getAccessToken(); - httpFacade = createHttpFacade("/api/resourcea", token); - handler = new AuthenticatedActionsHandler(deployment, httpFacade); - - assertFalse(handler.handledRequest()); - } - @Test public void testMappedPathEnforcementModeDisabled() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-disabled-enforce-mode-path.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-enforce-mode-path.json", true); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resource/public"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthzTestUtils.TestResponse response = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public"), response); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resourceb"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourceb"), response.clear()); assertFalse(context.isGranted()); - TestResponse response = TestResponse.class.cast(httpFacade.getResponse()); assertEquals(403, response.getStatus()); oauth.realm(REALM_NAME); @@ -323,28 +251,22 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { oauth.doLogin("marta", "password"); String token = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), null).getAccessToken(); - httpFacade = createHttpFacade("/api/resourcea", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), response.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resourceb", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourceb", token), response.clear()); assertFalse(context.isGranted()); - response = TestResponse.class.cast(httpFacade.getResponse()); assertEquals(403, response.getStatus()); - httpFacade = createHttpFacade("/api/resource/public", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public", token), response.clear()); assertTrue(context.isGranted()); } @Test public void testDisabledPathNoCache() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-disabled-path-nocache.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-path-nocache.json", true); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resource/public"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public"), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID); @@ -354,15 +276,13 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { clientResource.authorization().resources().resource(resource.getId()).remove(); // first request caches the path and the entry is invalidated due to the lifespan - httpFacade = createHttpFacade("/api/resource/all-public"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/all-public"), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); WaitUtils.pause(1000); // second request can not fail because entry should not be invalidated - httpFacade = createHttpFacade("/api/resource/all-public"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/all-public"), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); } @@ -379,8 +299,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { clientResource.authorization().permissions().resource().create(permission); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-disabled-path-nocache.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-path-nocache.json", true); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -390,12 +309,10 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/any-resource/test", token); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/any-resource/test", token), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/any-resource/test", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/any-resource/test", token), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); ResourceRepresentation resource = clientResource.authorization().resources() @@ -403,40 +320,19 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { clientResource.authorization().resources().resource(resource.getId()).remove(); - httpFacade = createHttpFacade("/api/any-resource/test", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/any-resource/test", token), new AuthzTestUtils.TestResponse()); assertFalse(context.isGranted()); } @Test public void testEnforcementModeDisabled() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-disabled-enforce-mode.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-enforce-mode.json", true); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resource/public"); - policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); - TestResponse response = TestResponse.class.cast(httpFacade.getResponse()); + AuthzTestUtils.TestResponse response = new AuthzTestUtils.TestResponse(); + policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public"), response); assertEquals(401, response.getStatus()); } - @Test - public void testDefaultWWWAuthenticateCorsHeader() { - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-disabled-enforce-mode-path.json")); - - deployment.setCors(true); - Map> headers = new HashMap<>(); - - headers.put(CorsHeaders.ORIGIN,Arrays.asList("http://localhost:8180")); - - oauth.realm(REALM_NAME); - oauth.clientId("public-client-test"); - oauth.doLogin("marta", "password"); - String token = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), null).getAccessToken(); - OIDCHttpFacade httpFacade = createHttpFacade("http://server/api/resource/public", HttpMethod.OPTIONS, token, headers, Collections.emptyMap(), null, deployment); - new AuthenticatedActionsHandler(deployment, httpFacade).handledRequest(); - assertEquals(HttpHeaders.WWW_AUTHENTICATE, headers.get(CorsHeaders.ACCESS_CONTROL_EXPOSE_HEADERS).get(0)); - } - @Test public void testMatchHttpVerbsToScopes() { ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID); @@ -451,8 +347,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { PermissionsResource permissions = clientResource.authorization().permissions(); permissions.resource().create(permission).close(); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-match-http-verbs-scopes.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-match-http-verbs-scopes.json", true); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); oauth.doLogin("marta", "password"); @@ -461,32 +356,28 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/resource-with-scope", token); - - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse); assertFalse("Should fail because resource does not have any scope named GET", context.isGranted()); - assertEquals(403, TestResponse.class.cast(httpFacade.getResponse()).getStatus()); + assertEquals(403, testResponse.getStatus()); resource.addScope("GET", "POST"); clientResource.authorization().resources().resource(resource.getId()).update(resource); - deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-match-http-verbs-scopes.json")); - policyEnforcer = deployment.getPolicyEnforcer(); + policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-match-http-verbs-scopes.json", true); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear()); assertTrue(context.isGranted()); // create a PATCH scope without associated it with the resource so that a PATCH request is denied accordingly even though // the scope exists on the server clientResource.authorization().scopes().create(new ScopeRepresentation("PATCH")); - httpFacade = createHttpFacade("/api/resource-with-scope", token, "PATCH"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "PATCH"), testResponse.clear()); assertFalse(context.isGranted()); ScopePermissionRepresentation postPermission = new ScopePermissionRepresentation(); @@ -497,8 +388,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { permissions.scope().create(postPermission).close(); - httpFacade = createHttpFacade("/api/resource-with-scope", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear()); assertFalse(context.isGranted()); postPermission = permissions.scope().findByName(postPermission.getName()); @@ -508,16 +398,14 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { permissions.scope().findById(postPermission.getId()).update(postPermission); - AuthzClient authzClient = getAuthzClient("default-keycloak.json"); + AuthzClient authzClient = policyEnforcer.getAuthzClient(); AuthorizationResponse authorize = authzClient.authorization(token).authorize(); token = authorize.getToken(); - httpFacade = createHttpFacade("/api/resource-with-scope", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear()); assertTrue(context.isGranted()); postPermission = permissions.scope().findByName(postPermission.getName()); @@ -527,12 +415,10 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { authorize = authzClient.authorization(token).authorize(); token = authorize.getToken(); - httpFacade = createHttpFacade("/api/resource-with-scope", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear()); assertFalse(context.isGranted()); - httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear()); assertTrue(context.isGranted()); postPermission = permissions.scope().findByName(postPermission.getName()); @@ -542,12 +428,10 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { authorize = authzClient.authorization(token).authorize(); token = authorize.getToken(); - httpFacade = createHttpFacade("/api/resource-with-scope", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear()); assertTrue(context.isGranted()); postPermission = permissions.scope().findByName(postPermission.getName()); @@ -561,12 +445,10 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { authorize = authzClient.authorization(token).authorize(request); token = authorize.getToken(); - httpFacade = createHttpFacade("/api/resource-with-scope", token); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear()); assertTrue(context.isGranted()); - httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear()); assertFalse(context.isGranted()); } @@ -584,13 +466,12 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { PermissionsResource permissions = clientResource.authorization().permissions(); permissions.resource().create(permission).close(); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/check-subject-token"); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only.json", true); + AuthzTestUtils.TestResponse testResponse = new AuthzTestUtils.TestResponse(); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/check-subject-token"), testResponse); assertFalse(context.isGranted()); - assertEquals(403, TestResponse.class.cast(httpFacade.getResponse()).getStatus()); + assertEquals(403, testResponse.getStatus()); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -600,9 +481,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - httpFacade = createHttpFacade("/api/check-subject-token", token); - - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/check-subject-token", token), testResponse.clear()); assertTrue(context.isGranted()); } @@ -620,9 +499,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { PermissionsResource permissions = clientResource.authorization().permissions(); permissions.resource().create(permission).close(); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); - OIDCHttpFacade httpFacade = createHttpFacade("/api/check-subject-token"); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only.json", true); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -632,14 +509,12 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); String token = response.getAccessToken(); - httpFacade = createHttpFacade("/api/check-subject-token", token); - - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/check-subject-token", token), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); oauth.doLogout(response.getRefreshToken(), null); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/check-subject-token", token), new AuthzTestUtils.TestResponse()); assertFalse(context.isGranted()); } @@ -670,13 +545,11 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { PermissionsResource permissions = clientResource.authorization().permissions(); permissions.resource().create(permission).close(); - KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-no-lazyload.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-no-lazyload.json", true); assertEquals(205, policyEnforcer.getPaths().size()); - deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-lazyload.json")); - policyEnforcer = deployment.getPolicyEnforcer(); + policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-lazyload.json", true); assertEquals(0, policyEnforcer.getPathMatcher().getPathCache().size()); assertEquals(0, policyEnforcer.getPaths().size()); @@ -688,15 +561,13 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { String token = response.getAccessToken(); for (int i = 0; i < 101; i++) { - OIDCHttpFacade httpFacade = createHttpFacade("/api/" + i, token); - policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/" + i, token), new AuthzTestUtils.TestResponse()); } assertEquals(101, policyEnforcer.getPathMatcher().getPathCache().size()); for (int i = 101; i < 200; i++) { - OIDCHttpFacade httpFacade = createHttpFacade("/api/" + i, token); - policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/" + i, token), new AuthzTestUtils.TestResponse()); } assertEquals(200, policyEnforcer.getPathMatcher().getPathCache().size()); @@ -707,11 +578,9 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { clientResource.authorization().resources().resource(resource.getId()).remove(); - deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-lazyload-with-paths.json")); - policyEnforcer = deployment.getPolicyEnforcer(); + policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-lazyload-with-paths.json", true); - OIDCHttpFacade httpFacade = createHttpFacade("/api/0", token); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/0", token), new AuthzTestUtils.TestResponse()); assertTrue(context.isGranted()); } @@ -732,9 +601,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { response.close(); try { - KeycloakDeployment deployment = KeycloakDeploymentBuilder - .build(getAdapterConfiguration("enforcer-paths-use-method-config.json")); - PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer(); + PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-paths-use-method-config.json", true); oauth.realm(REALM_NAME); oauth.clientId("public-client-test"); @@ -743,8 +610,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse tokeResponse = oauth.doAccessTokenRequest(code, null); String token = tokeResponse.getAccessToken(); - OIDCHttpFacade httpFacade = createHttpFacade("/api-method/foo", token); - AuthorizationContext context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api-method/foo", token), new AuthzTestUtils.TestResponse()); // GET is disabled in the config assertTrue(context.isGranted()); @@ -757,8 +623,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { assertTrue(PolicyEnforcerConfig.ScopeEnforcementMode.DISABLED.equals(methods.get(0).getScopesEnforcementMode())); // other verbs should be protected - httpFacade = createHttpFacade("/api-method/foo", token, "POST"); - context = policyEnforcer.enforce(new HttpAuthzRequest(httpFacade), new HttpAuthzResponse(httpFacade)); + context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api-method/foo", token, "POST"), new AuthzTestUtils.TestResponse()); assertFalse(context.isGranted()); } finally { @@ -817,14 +682,6 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { } } - private InputStream getAdapterConfiguration(String fileName) { - try { - return httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + fileName)); - } catch (IOException e) { - throw new AssertionError("Unexpected I/O error while dealing with configuration", e); - } - } - private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) { ResourceRepresentation representation = new ResourceRepresentation(); @@ -846,244 +703,4 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { ClientRepresentation representation = clients.findByClientId(name).get(0); return clients.get(representation.getId()); } - - private OIDCHttpFacade createHttpFacade(String path, String method, String token, Map> headers, Map> parameters, InputStream requestBody, KeycloakDeployment deployment) { - return createHttpFacade(path, method, token, headers, parameters, requestBody, deployment, null); - } - - private OIDCHttpFacade createHttpFacade(String path, String method, String token, Map> headers, Map> parameters, InputStream requestBody, KeycloakDeployment deployment, Function parameterFunction) { - return new OIDCHttpFacade() { - Request request; - Response response; - - @Override - public KeycloakSecurityContext getSecurityContext() { - if (token != null) { - AccessToken accessToken; - try { - accessToken = new JWSInput(token).readJsonContent(AccessToken.class); - } catch (JWSInputException cause) { - throw new RuntimeException(cause); - } - return new RefreshableKeycloakSecurityContext(deployment, token, accessToken, null, null, null); - } - return null; - } - - @Override - public Request getRequest() { - if (request == null) { - request = createHttpRequest(path, method, headers, parameters, requestBody, parameterFunction); - } - return request; - } - - @Override - public Response getResponse() { - if (response == null) { - response = createHttpResponse(headers); - } - return response; - } - - @Override - public X509Certificate[] getCertificateChain() { - return new X509Certificate[0]; - } - }; - } - - private OIDCHttpFacade createHttpFacade(String path, String token) { - return createHttpFacade(path, null, token, new HashMap<>(), new HashMap<>(), null, null); - } - - private OIDCHttpFacade createHttpFacade(String path, String token, String method) { - return createHttpFacade(path, method, token, new HashMap<>(), new HashMap<>(), null, null); - } - - private OIDCHttpFacade createHttpFacade(String path) { - return createHttpFacade(path, null, null, new HashMap<>(), new HashMap<>(), null, null); - } - - private OIDCHttpFacade createHttpFacade(String path, String token, Function parameterFunction) { - return createHttpFacade(path, null, token, new HashMap<>(), new HashMap<>(), null, null, parameterFunction); - } - - private Response createHttpResponse(Map> headers) { - return new TestResponse(headers); - } - - private Request createHttpRequest(String path, String method, Map> headers, Map> parameters, InputStream requestBody, Function parameterFunction) { - if (parameterFunction == null) { - parameterFunction = param -> { - List values = parameters.getOrDefault(param, Collections.emptyList()); - - if (!values.isEmpty()) { - return values.get(0); - } - - return null; - }; - } - Function finalParameterFunction = parameterFunction; - return new Request() { - - private InputStream inputStream; - - @Override - public String getMethod() { - return method == null ? "GET" : method; - } - - @Override - public String getURI() { - return path; - } - - @Override - public String getRelativePath() { - return path; - } - - @Override - public boolean isSecure() { - return true; - } - - @Override - public String getFirstParam(String param) { - return finalParameterFunction.apply(param); - } - - @Override - public String getQueryParamValue(String param) { - return getFirstParam(param); - } - - @Override - public Cookie getCookie(String cookieName) { - return null; - } - - @Override - public String getHeader(String name) { - List headers = getHeaders(name); - - if (!headers.isEmpty()) { - return headers.get(0); - } - - return null; - } - - @Override - public List getHeaders(String name) { - return headers.getOrDefault(name, Collections.emptyList()); - } - - @Override - public InputStream getInputStream() { - return getInputStream(false); - } - - @Override - public InputStream getInputStream(boolean buffer) { - if (requestBody == null) { - return new ByteArrayInputStream(new byte[] {}); - } - - if (inputStream != null) { - return inputStream; - } - - if (buffer) { - return inputStream = new BufferedInputStream(requestBody); - } - - return requestBody; - } - - @Override - public String getRemoteAddr() { - return "user-remote-addr"; - } - - @Override - public void setError(AuthenticationError error) { - - } - - @Override - public void setError(LogoutError error) { - - } - }; - } - - protected AuthzClient getAuthzClient(String fileName) { - return AuthzClient.create(getAdapterConfiguration(fileName)); - } - - private class TestResponse implements Response { - - private final Map> headers; - private int status; - - public TestResponse(Map> headers) { - this.headers = headers; - } - - @Override - public void setStatus(int status) { - this.status = status; - } - - public int getStatus() { - return status; - } - - @Override - public void addHeader(String name, String value) { - setHeader(name, value); - } - - @Override - public void setHeader(String name, String value) { - headers.put(name, Arrays.asList(value)); - } - - public Map> getHeaders() { - return headers; - } - - @Override - public void resetCookie(String name, String path) { - - } - - @Override - public void setCookie(String name, String value, String path, String domain, int maxAge, boolean secure, boolean httpOnly) { - - } - - @Override - public OutputStream getOutputStream() { - return null; - } - - @Override - public void sendError(int code) { - status = code; - } - - @Override - public void sendError(int code, String message) { - status = code; - } - - @Override - public void end() { - - } - } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json index 8ca02533b1..777840f89f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json @@ -1,30 +1,26 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "claim-information-point": { - "claims": { - "claim-b": "claim-b" - } - }, - "paths": [ - { - "path": "/api/resourcea", - "claim-information-point": { - "claims": { - "claim-a": "{request.parameter['claim-a']}" - }, - "my-custom-cip": { - "claim-value": "test" - } + "claim-information-point": { + "claims": { + "claim-b": "claim-b" + } + }, + "paths": [ + { + "path": "/api/resourcea", + "claim-information-point": { + "claims": { + "claim-a": "{request.parameter['claim-a']}" + }, + "my-custom-cip": { + "claim-value": "test" } } - ] - } + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only.json index 5f7f4e9e97..6482606925 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only.json @@ -1,11 +1,8 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" - }, - "bearer-only": true, - "policy-enforcer": {} + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-claims-provider.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-claims-provider.json index 3b74027391..122bf26b21 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-claims-provider.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-claims-provider.json @@ -1,105 +1,101 @@ { "realm": "test-realm-authz", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "test-app-authz", - "bearer-only": true, "credentials": { "secret": "secret" }, - "policy-enforcer": { - "paths": [ - { - "path": "/claims-provider", - "methods": [ - { - "method": "POST", - "scopes": [ - "create" - ] - } - ], - "claim-information-point": { + "paths": [ + { + "path": "/claims-provider", + "methods": [ + { + "method": "POST", + "scopes": [ + "create" + ] + } + ], + "claim-information-point": { + "claims": { + "claim-from-request-parameter": "{request.parameter['a']}", + "claim-from-header": "{request.header['b']}", + "claim-from-cookie": "{request.cookie['c']}", + "claim-from-remoteAddr": "{request.remoteAddr}", + "claim-from-method": "{request.method}", + "claim-from-uri": "{request.uri}", + "claim-from-relativePath": "{request.relativePath}", + "claim-from-secure": "{request.secure}", + "claim-from-json-body-object": "{request.body['/a/b/c']}", + "claim-from-json-body-array": "{request.body['/d/1']}", + "claim-from-json-body-number": "{request.body['/e/number']}", + "claim-from-body": "{request.body}", + "claim-from-static-value": "static value", + "claim-from-multiple-static-value": ["static", "value"], + "param-replace-multiple-placeholder": "Test {keycloak.access_token['/custom_claim/0']} and {request.parameter['a']} " + } + } + }, + { + "path": "/claims-from-body-json-object", + "methods": [ + { + "method": "POST", + "scopes": [ + "create" + ] + } + ], + "claim-information-point": { + "claims": { + "individualRoles": "{request.body['/Individual/individualRoles']}" + } + } + }, + { + "path": "/http-post-claim-provider", + "claim-information-point": { + "http": { "claims": { - "claim-from-request-parameter": "{request.parameter['a']}", - "claim-from-header": "{request.header['b']}", - "claim-from-cookie": "{request.cookie['c']}", - "claim-from-remoteAddr": "{request.remoteAddr}", - "claim-from-method": "{request.method}", - "claim-from-uri": "{request.uri}", - "claim-from-relativePath": "{request.relativePath}", - "claim-from-secure": "{request.secure}", - "claim-from-json-body-object": "{request.body['/a/b/c']}", - "claim-from-json-body-array": "{request.body['/d/1']}", - "claim-from-json-body-number": "{request.body['/e/number']}", - "claim-from-body": "{request.body}", - "claim-from-static-value": "static value", - "claim-from-multiple-static-value": ["static", "value"], - "param-replace-multiple-placeholder": "Test {keycloak.access_token['/custom_claim/0']} and {request.parameter['a']} " - } - } - }, - { - "path": "/claims-from-body-json-object", - "methods": [ - { - "method": "POST", - "scopes": [ - "create" - ] - } - ], - "claim-information-point": { - "claims": { - "individualRoles": "{request.body['/Individual/individualRoles']}" - } - } - }, - { - "path": "/http-post-claim-provider", - "claim-information-point": { - "http": { - "claims": { - "claim-a": "/a", - "claim-d": "/d", - "claim-d0": "/d/0", - "claim-d-all": ["/d/0", "/d/1"] - }, - "url": "http://localhost:8989/post-claim-information-provider", - "method": "POST", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "header-b": ["header-b-value1", "header-b-value2"], - "Authorization": "Bearer {keycloak.access_token}" - }, - "parameters": { - "param-a": ["param-a-value1", "param-a-value2"], - "param-subject": "{keycloak.access_token['/sub']}", - "param-user-name": "{keycloak.access_token['/preferred_username']}", - "param-other-claims": "{keycloak.access_token['/custom_claim']}" - } - } - } - }, - { - "path": "/http-get-claim-provider", - "claim-information-point": { - "http": { - "url": "http://localhost:8989/get-claim-information-provider", - "method": "get", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "header-b": ["header-b-value1", "header-b-value2"], - "Authorization": "Bearer {keycloak.access_token}" - }, - "parameters": { - "param-a": ["param-a-value1", "param-a-value2"], - "param-subject": "{keycloak.access_token['/sub']}", - "param-user-name": "{keycloak.access_token['/preferred_username']}" - } + "claim-a": "/a", + "claim-d": "/d", + "claim-d0": "/d/0", + "claim-d-all": ["/d/0", "/d/1"] + }, + "url": "http://localhost:8989/post-claim-information-provider", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded", + "header-b": ["header-b-value1", "header-b-value2"], + "Authorization": "Bearer {keycloak.access_token}" + }, + "parameters": { + "param-a": ["param-a-value1", "param-a-value2"], + "param-subject": "{keycloak.access_token['/sub']}", + "param-user-name": "{keycloak.access_token['/preferred_username']}", + "param-other-claims": "{keycloak.access_token['/custom_claim']}" } } } - ] - } + }, + { + "path": "/http-get-claim-provider", + "claim-information-point": { + "http": { + "url": "http://localhost:8989/get-claim-information-provider", + "method": "get", + "headers": { + "Content-Type": "application/x-www-form-urlencoded", + "header-b": ["header-b-value1", "header-b-value2"], + "Authorization": "Bearer {keycloak.access_token}" + }, + "parameters": { + "param-a": ["param-a-value1", "param-a-value2"], + "param-subject": "{keycloak.access_token['/sub']}", + "param-user-name": "{keycloak.access_token['/preferred_username']}" + } + } + } + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-path-cip.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-path-cip.json index 59c7d64aa2..a757ace7e4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-path-cip.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-path-cip.json @@ -1,32 +1,28 @@ { "realm": "test-realm-authz", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "test-app-authz", - "bearer-only": true, "credentials": { "secret": "secret" }, - "policy-enforcer": { - "paths": [ - { - "path": "/v1/product/*", - "methods": [ - { - "method": "POST", - "scopes": [ - "create" - ] - } - ], - "claim-information-point": { - "claims": { - "claim-a": "{request.parameter['a']}", - "claim-b": "{request.header['b']}", - "claim-c": "{request.cookie['c']}" - } + "paths": [ + { + "path": "/v1/product/*", + "methods": [ + { + "method": "POST", + "scopes": [ + "create" + ] + } + ], + "claim-information-point": { + "claims": { + "claim-a": "{request.parameter['a']}", + "claim-b": "{request.header['b']}", + "claim-c": "{request.cookie['c']}" } } - ] - } + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-paths-same-name.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-paths-same-name.json index 35ebeb630c..7cccc8a87b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-paths-same-name.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-paths-same-name.json @@ -1,58 +1,54 @@ { "realm": "test-realm-authz", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "test-app-authz", - "bearer-only": true, "credentials": { "secret": "secret" }, - "policy-enforcer": { - "paths": [ - { - "path": "/v1/product/*", - "methods": [ - { - "method": "POST", - "scopes": [ - "create" - ] - } - ] - }, - { - "path": "/v1/product/*", - "methods": [ - { - "method": "GET", - "scopes": [ - "view" - ] - } - ] - }, - { - "path": "/v1/product/*", - "methods": [ - { - "method": "PUT", - "scopes": [ - "update" - ] - } - ] - }, - { - "path": "/v1/product/*", - "methods": [ - { - "method": "DELETE", - "scopes": [ - "delete" - ] - } - ] - } - ] - } + "paths": [ + { + "path": "/v1/product/*", + "methods": [ + { + "method": "POST", + "scopes": [ + "create" + ] + } + ] + }, + { + "path": "/v1/product/*", + "methods": [ + { + "method": "GET", + "scopes": [ + "view" + ] + } + ] + }, + { + "path": "/v1/product/*", + "methods": [ + { + "method": "PUT", + "scopes": [ + "update" + ] + } + ] + }, + { + "path": "/v1/product/*", + "methods": [ + { + "method": "DELETE", + "scopes": [ + "delete" + ] + } + ] + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode-path.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode-path.json index 878a9bce5f..93793d73a1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode-path.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode-path.json @@ -1,19 +1,15 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "paths": [ - { - "name": "Resource B", - "path": "/api/resource/public", - "enforcement-mode": "DISABLED" - } - ] - } + "paths": [ + { + "name": "Resource B", + "path": "/api/resource/public", + "enforcement-mode": "DISABLED" + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode.json index dbf85cb50c..87f21c1963 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode.json @@ -1,19 +1,15 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "enforcement-mode": "DISABLED", - "paths": [ - { - "name": "Resource B", - "path": "/api/resource/public" - } - ] - } + "enforcement-mode": "DISABLED", + "paths": [ + { + "name": "Resource B", + "path": "/api/resource/public" + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-path-nocache.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-path-nocache.json index c20e9fae08..2629d853ab 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-path-nocache.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-path-nocache.json @@ -1,31 +1,27 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "path-cache": { - "lifespan": 1 + "path-cache": { + "lifespan": 1 + }, + "paths": [ + { + "name": "Resource B", + "path": "/api/resource/public", + "enforcement-mode": "DISABLED" }, - "paths": [ - { - "name": "Resource B", - "path": "/api/resource/public", - "enforcement-mode": "DISABLED" - }, - { - "name": "Nonexistent", - "path": "/api/resource/all-public/*", - "enforcement-mode": "DISABLED" - }, - { - "name": "Static Test Resource", - "path": "/api/any-resource/test" - } - ] - } + { + "name": "Nonexistent", + "path": "/api/resource/all-public/*", + "enforcement-mode": "DISABLED" + }, + { + "name": "Static Test Resource", + "path": "/api/any-resource/test" + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-entitlement-claims-test.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-entitlement-claims-test.json index b01909d920..efbdba00d5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-entitlement-claims-test.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-entitlement-claims-test.json @@ -1,29 +1,26 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "policy-enforcer": { - "paths": [ - { - "path": "/api/bank/account/{id}/withdrawal", - "methods": [ - { - "method": "POST", - "scopes": [ - "withdrawal" - ] - } - ], - "claim-information-point": { - "claims": { - "withdrawal.amount": "{request.parameter['withdrawal.amount']}" - } + "paths": [ + { + "path": "/api/bank/account/{id}/withdrawal", + "methods": [ + { + "method": "POST", + "scopes": [ + "withdrawal" + ] + } + ], + "claim-information-point": { + "claims": { + "withdrawal.amount": "{request.parameter['withdrawal.amount']}" } } - ] - } + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload-with-paths.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload-with-paths.json index 0c213f6415..de2e3f6842 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload-with-paths.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload-with-paths.json @@ -1,19 +1,15 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "lazy-load-paths": true, - "paths": [ - { - "path": "/disabled", - "enforcement-mode": "DISABLED" - } - ] - } + "lazy-load-paths": true, + "paths": [ + { + "path": "/disabled", + "enforcement-mode": "DISABLED" + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload.json index be348a3f8c..9de3180bcc 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload.json @@ -1,13 +1,9 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "lazy-load-paths": true - } + "lazy-load-paths": true } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-match-http-verbs-scopes.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-match-http-verbs-scopes.json index 1daafa05f5..6d67d75452 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-match-http-verbs-scopes.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-match-http-verbs-scopes.json @@ -1,13 +1,9 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "http-method-as-scope": true - } + "http-method-as-scope": true } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-no-lazyload.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-no-lazyload.json index 5f7f4e9e97..6482606925 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-no-lazyload.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-no-lazyload.json @@ -1,11 +1,8 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" - }, - "bearer-only": true, - "policy-enforcer": {} + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-on-deny-redirect.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-on-deny-redirect.json index c254401003..54d3746b5a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-on-deny-redirect.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-on-deny-redirect.json @@ -1,12 +1,9 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "policy-enforcer": { - "on-deny-redirect-to": "/accessDenied" - } + "on-deny-redirect-to": "/accessDenied" } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths-use-method-config.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths-use-method-config.json index a2f1cbb883..0038f44ac5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths-use-method-config.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths-use-method-config.json @@ -1,27 +1,23 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "lazy-load-paths": true, - "paths": [ - { - "path": "/api-method/*", - "methods": [ - { - "method": "GET", - "scopes": [ - "withdrawal" - ], - "scopes-enforcement-mode": "DISABLED" - } - ] - } - ] - } + "lazy-load-paths": true, + "paths": [ + { + "path": "/api-method/*", + "methods": [ + { + "method": "GET", + "scopes": [ + "withdrawal" + ], + "scopes-enforcement-mode": "DISABLED" + } + ] + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths.json index 0221a18667..50e81da9b7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths.json @@ -1,24 +1,20 @@ { "realm": "authz-test", - "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-test", + "auth-server-url": "http://localhost:8180/auth", "credentials": { "secret": "secret" }, - "bearer-only": true, - "policy-enforcer": { - "lazy-load-paths": true, - "paths": [ - { - "name": "Root", - "path": "/*", - "enforcement-mode": "DISABLED" - }, - { - "name": "Resource A", - "path": "/api/*" - } - ] - } + "lazy-load-paths": true, + "paths": [ + { + "name": "Root", + "path": "/*", + "enforcement-mode": "DISABLED" + }, + { + "name": "Resource A", + "path": "/api/*" + } + ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-uma-claims-test.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-uma-claims-test.json index 9729103db9..c858956b8c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-uma-claims-test.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-uma-claims-test.json @@ -1,31 +1,27 @@ { "realm": "authz-test", "auth-server-url": "http://localhost:8180/auth", - "ssl-required": "external", "resource": "resource-server-uma-test", - "bearer-only": true, "credentials": { "secret": "secret" }, - "policy-enforcer": { - "user-managed-access": {}, - "paths": [ - { - "path": "/api/bank/account/{id}/withdrawal", - "methods": [ - { - "method": "POST", - "scopes": [ - "withdrawal" - ] - } - ], - "claim-information-point": { - "claims": { - "withdrawal.amount": "{request.parameter['withdrawal.amount']}" - } + "user-managed-access": {}, + "paths": [ + { + "path": "/api/bank/account/{id}/withdrawal", + "methods": [ + { + "method": "POST", + "scopes": [ + "withdrawal" + ] + } + ], + "claim-information-point": { + "claims": { + "withdrawal.amount": "{request.parameter['withdrawal.amount']}" } } - ] - } + } + ] }