From cd947ce3bca58ed89e4489cc651abf1ddd314006 Mon Sep 17 00:00:00 2001
From: mposolda
Date: Fri, 16 Aug 2024 11:07:57 +0200
Subject: [PATCH] Removing policy-enforcer from Keycloak repository closes
#32191
Signed-off-by: mposolda
---
authz/policy-enforcer/pom.xml | 54 --
.../adapters/authorization/PathCache.java | 203 -----
.../authorization/PathConfigMatcher.java | 293 --------
.../authorization/PolicyEnforcer.java | 669 -----------------
.../authorization/TokenPrincipal.java | 56 --
.../cip/ClaimsInformationPointProvider.java | 74 --
...ClaimsInformationPointProviderFactory.java | 37 -
.../HttpClaimInformationPointProvider.java | 207 -----
...pClaimInformationPointProviderFactory.java | 45 --
.../spi/ClaimInformationPointProvider.java | 30 -
.../ClaimInformationPointProviderFactory.java | 35 -
.../elytron/ElytronPolicyEnforcerFilter.java | 53 --
.../PolicyEnforcerServletContextListener.java | 81 --
.../elytron/ServletHttpRequest.java | 139 ----
.../elytron/ServletHttpResponse.java | 58 --
.../jakarta/ServletPolicyEnforcerFilter.java | 125 ----
.../spi/ConfigurationResolver.java | 36 -
.../authorization/spi/HttpRequest.java | 114 ---
.../authorization/spi/HttpResponse.java | 48 --
.../authorization/util/JsonUtils.java | 78 --
...oakSecurityContextPlaceHolderResolver.java | 55 --
.../util/PlaceHolderResolver.java | 30 -
.../authorization/util/PlaceHolders.java | 112 ---
.../util/RequestPlaceHolderResolver.java | 170 -----
...p.spi.ClaimInformationPointProviderFactory | 19 -
authz/pom.xml | 1 -
pom.xml | 5 -
.../testsuite/util/AuthzTestUtils.java | 219 ------
.../authz/AuthzClientCredentialsTest.java | 18 +-
.../ClaimInformationPointProviderTest.java | 317 --------
.../authz/admin/EnforcerConfigTest.java | 84 ---
.../authz/admin/MyCustomCIPFactory.java | 57 --
.../authz/admin/PolicyEnforcerClaimsTest.java | 386 ----------
.../authz/admin/PolicyEnforcerTest.java | 706 ------------------
...p.spi.ClaimInformationPointProviderFactory | 18 -
.../enforcer-bearer-only-with-cip.json | 26 -
.../enforcer-bearer-only.json | 8 -
.../enforcer-config-claims-provider.json | 101 ---
.../enforcer-config-path-cip.json | 28 -
.../enforcer-config-paths-same-name.json | 54 --
.../enforcer-disabled-enforce-mode-path.json | 15 -
.../enforcer-disabled-enforce-mode.json | 15 -
.../enforcer-disabled-path-nocache.json | 27 -
.../enforcer-entitlement-claims-test.json | 26 -
.../enforcer-lazyload-with-paths.json | 15 -
.../authorization-test/enforcer-lazyload.json | 9 -
.../enforcer-match-http-verbs-scopes.json | 9 -
.../enforcer-no-lazyload.json | 8 -
.../enforcer-on-deny-redirect.json | 9 -
.../enforcer-paths-use-method-config.json | 23 -
.../authorization-test/enforcer-paths.json | 20 -
.../enforcer-uma-claims-test.json | 27 -
.../authorization-test/test-authz-realm.json | 48 --
testsuite/integration-arquillian/util/pom.xml | 4 -
54 files changed, 12 insertions(+), 5092 deletions(-)
delete mode 100755 authz/policy-enforcer/pom.xml
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathCache.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathConfigMatcher.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/TokenPrincipal.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProvider.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProviderFactory.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProvider.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProviderFactory.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProvider.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProviderFactory.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpResponse.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/ConfigurationResolver.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpRequest.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpResponse.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/JsonUtils.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/KeycloakSecurityContextPlaceHolderResolver.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolderResolver.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolders.java
delete mode 100644 authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/RequestPlaceHolderResolver.java
delete mode 100644 authz/policy-enforcer/src/main/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory
delete mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AuthzTestUtils.java
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ClaimInformationPointProviderTest.java
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/EnforcerConfigTest.java
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/MyCustomCIPFactory.java
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerClaimsTest.java
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerTest.java
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-claims-provider.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-path-cip.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-paths-same-name.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode-path.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-path-nocache.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-entitlement-claims-test.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload-with-paths.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-match-http-verbs-scopes.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-no-lazyload.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-on-deny-redirect.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths-use-method-config.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-uma-claims-test.json
delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/test-authz-realm.json
diff --git a/authz/policy-enforcer/pom.xml b/authz/policy-enforcer/pom.xml
deleted file mode 100755
index fae7b26126..0000000000
--- a/authz/policy-enforcer/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
- org.keycloak
- keycloak-authz-parent
- 999.0.0-SNAPSHOT
- ../pom.xml
-
- 4.0.0
-
- keycloak-policy-enforcer-tests
- Keycloak Authz: Policy Enforcer for tests
- Keycloak Policy Enforcer. This module is supposed to be used just in the Keycloak repository for the testsuite. It is NOT supposed to be used by the 3rd party applications.
- For the use by 3rd party applications, please use `org.keycloak:keycloak-policy-enforcer` module.
- jar
-
-
-
- org.keycloak
- keycloak-authz-client-tests
-
-
-
-
- jakarta.servlet
- jakarta.servlet-api
- true
-
-
- org.wildfly.security
- wildfly-elytron-http-oidc
- true
-
-
-
-
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathCache.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathCache.java
deleted file mode 100644
index 8aa66a9613..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathCache.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.LockSupport;
-
-import org.keycloak.common.util.Time;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
-
-/**
- * A simple LRU cache implementation supporting expiration and maximum number of entries.
- *
- * @author Pedro Igor
- */
-public class PathCache {
-
- /**
- * The load factor.
- */
- private static final float DEFAULT_LOAD_FACTOR = 0.75f;
-
- private final Map cache;
-
- private final AtomicBoolean writing = new AtomicBoolean(false);
-
- private final long maxAge;
- private final boolean enabled;
- private final Map paths;
-
- /**
- * Creates a new instance.
- * @param maxEntries the maximum number of entries to keep in the cache
- * @param maxAge the time in milliseconds that an entry can stay in the cache. If {@code -1}, entries never expire
- * @param paths the pre-configured paths
- */
- PathCache(final int maxEntries, long maxAge,
- Map paths) {
- cache = Collections.synchronizedMap(new LinkedHashMap(16, DEFAULT_LOAD_FACTOR, true) {
- @Override
- protected boolean removeEldestEntry(Map.Entry eldest) {
- return cache.size() > maxEntries;
- }
- });
- this.maxAge = maxAge;
- this.enabled = ! (maxAge < -1 || (maxAge > -1 && maxAge <= 0));
- this.paths = paths;
- }
-
- public void put(String uri, PathConfig newValue) {
- if (!enabled) {
- if (newValue != null) {
- // if disabled we also remove from the pre-defined paths map
- markForInvalidation(newValue);
- }
- return;
- }
-
- try {
- if (parkForWriteAndCheckInterrupt()) {
- return;
- }
-
- CacheEntry cacheEntry = cache.get(uri);
-
- if (cacheEntry == null) {
- cache.put(uri, new CacheEntry(uri, newValue, maxAge));
- }
- } finally {
- writing.lazySet(false);
- }
- }
-
- private void markForInvalidation(PathConfig newValue) {
- PathConfig pathConfig = paths.get(newValue.getPath());
-
- if (pathConfig != null && !pathConfig.isStatic()) {
- // invalidate the configuration so that the path config is reload based on latest changes on the server
- pathConfig.invalidate();
- }
- }
-
- public boolean containsKey(String uri) {
- return cache.containsKey(uri);
- }
-
- public PathConfig get(String uri) {
- if (parkForReadAndCheckInterrupt()) {
- return null;
- }
-
- CacheEntry cached = cache.get(uri);
-
- if (cached != null) {
- return removeIfExpired(cached);
- }
-
- return null;
- }
-
- public void remove(String key) {
- try {
- if (parkForWriteAndCheckInterrupt()) {
- return;
- }
-
- cache.remove(key);
- } finally {
- writing.lazySet(false);
- }
- }
-
- private PathConfig removeIfExpired(CacheEntry cached) {
- if (cached == null) {
- return null;
- }
-
- PathConfig config = cached.value();
-
- if (cached.isExpired()) {
- remove(cached.key());
-
- if (config != null && config.getPath() != null) {
- // also remove from pre-defined paths map so that changes on the server are properly reflected
- markForInvalidation(config);
- }
- return null;
- }
-
- return config;
- }
-
- private boolean parkForWriteAndCheckInterrupt() {
- while (!writing.compareAndSet(false, true)) {
- LockSupport.parkNanos(1L);
- if (Thread.interrupted()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean parkForReadAndCheckInterrupt() {
- while (writing.get()) {
- LockSupport.parkNanos(1L);
- if (Thread.interrupted()) {
- return true;
- }
- }
- return false;
- }
-
- public int size() {
- return cache.size();
- }
-
- private static final class CacheEntry {
-
- final String key;
- final PathConfig value;
- final long expiration;
-
- CacheEntry(String key, PathConfig value, long maxAge) {
- this.key = key;
- this.value = value;
- if(maxAge == -1) {
- expiration = -1;
- } else {
- expiration = Time.currentTimeMillis() + maxAge;
- }
- }
-
- String key() {
- return key;
- }
-
- PathConfig value() {
- return value;
- }
-
- boolean isExpired() {
- return expiration != -1 ? Time.currentTimeMillis() > expiration : false;
- }
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathConfigMatcher.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathConfigMatcher.java
deleted file mode 100644
index 2e1b75a3fc..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PathConfigMatcher.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jboss.logging.Logger;
-import org.keycloak.authorization.client.AuthzClient;
-import org.keycloak.authorization.client.resource.ProtectedResource;
-import org.keycloak.common.util.PathMatcher;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathCacheConfig;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-
-/**
- * @author Pedro Igor
- */
-public class PathConfigMatcher extends PathMatcher {
-
- private static Logger LOGGER = Logger.getLogger(PolicyEnforcer.class);
-
- private final Map paths;
- private final PathCache pathCache;
- private final AuthzClient authzClient;
- private final PolicyEnforcerConfig enforcerConfig;
-
- PathConfigMatcher(PolicyEnforcerConfig enforcerConfig, AuthzClient authzClient) {
- this.enforcerConfig = enforcerConfig;
- PathCacheConfig cacheConfig = enforcerConfig.getPathCacheConfig();
-
- if (cacheConfig == null) {
- cacheConfig = new PathCacheConfig();
- }
-
- this.authzClient = authzClient;
- this.paths = configurePaths();
- this.pathCache = new PathCache(cacheConfig.getMaxEntries(), cacheConfig.getLifespan(), paths);
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Initialization complete. Path configuration:");
- for (PathConfig pathConfig : this.paths.values()) {
- LOGGER.debug(pathConfig);
- }
- }
- }
-
- @Override
- public PathConfig matches(String targetUri) {
- PathConfig pathConfig = pathCache.get(targetUri);
-
- if (pathCache.containsKey(targetUri) || pathConfig != null) {
- return pathConfig;
- }
-
- pathConfig = super.matches(targetUri);
-
- if (enforcerConfig.getLazyLoadPaths() || enforcerConfig.getPathCacheConfig() != null) {
- if ((pathConfig == null || pathConfig.isInvalidated() || pathConfig.getPath().contains("*"))) {
- try {
- List matchingResources = authzClient.protection().resource().findByMatchingUri(targetUri);
-
- if (matchingResources.isEmpty()) {
- // if this config is invalidated (e.g.: due to cache expiration) we remove and return null
- if (pathConfig != null && pathConfig.isInvalidated()) {
- paths.remove(targetUri);
- return null;
- }
- } else {
- Map> cipConfig = null;
- PolicyEnforcerConfig.EnforcementMode enforcementMode = PolicyEnforcerConfig.EnforcementMode.ENFORCING;
- ResourceRepresentation targetResource = matchingResources.get(0);
- List methodConfig = null;
- boolean isStatic = false;
-
- if (pathConfig != null) {
- cipConfig = pathConfig.getClaimInformationPointConfig();
- enforcementMode = pathConfig.getEnforcementMode();
- methodConfig = pathConfig.getMethods();
- isStatic = pathConfig.isStatic();
- } else {
- for (PathConfig existingPath : paths.values()) {
- if (targetResource.getId().equals(existingPath.getId())
- && existingPath.isStatic()
- && !org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode.DISABLED.equals(existingPath.getEnforcementMode())) {
- return null;
- }
- }
- }
-
- pathConfig = PathConfig.createPathConfigs(targetResource).iterator().next();
-
- if (cipConfig != null) {
- pathConfig.setClaimInformationPointConfig(cipConfig);
- }
-
- if (methodConfig != null) {
- pathConfig.setMethods(methodConfig);
- }
-
- pathConfig.setStatic(isStatic);
- pathConfig.setEnforcementMode(enforcementMode);
- }
- } catch (Exception cause) {
- LOGGER.errorf(cause, "Could not lazy load resource with path [" + targetUri + "] from server");
- return null;
- }
- }
- }
-
- pathCache.put(targetUri, pathConfig);
-
- return pathConfig;
- }
-
- @Override
- protected String getPath(PathConfig entry) {
- return entry.getPath();
- }
-
- @Override
- protected Collection getPaths() {
- return paths.values();
- }
-
- public PathCache getPathCache() {
- return pathCache;
- }
-
- @Override
- protected PathConfig resolvePathConfig(PathConfig originalConfig, String path) {
- if (originalConfig.hasPattern()) {
- ProtectedResource resource = authzClient.protection().resource();
-
- // search by an exact match
- List search = resource.findByUri(path);
-
- // if exact match not found, try to obtain from current path the parent path.
- // if path is /resource/1/test and pattern from pathConfig is /resource/{id}/*, parent path is /resource/1
- // this logic allows to match sub resources of a resource instance (/resource/1) to the parent resource,
- // so any permission granted to parent also applies to sub resources
- if (search.isEmpty()) {
- search = resource.findByUri(buildUriFromTemplate(originalConfig.getPath(), path, true));
- }
-
- if (!search.isEmpty()) {
- ResourceRepresentation targetResource = search.get(0);
- PathConfig config = PathConfig.createPathConfigs(targetResource).iterator().next();
-
- config.setScopes(originalConfig.getScopes());
- config.setMethods(originalConfig.getMethods());
- config.setParentConfig(originalConfig);
- config.setEnforcementMode(originalConfig.getEnforcementMode());
- config.setClaimInformationPointConfig(originalConfig.getClaimInformationPointConfig());
-
- return config;
- }
- }
-
- return null;
- }
-
- public void removeFromCache(String pathConfig) {
- pathCache.remove(pathConfig);
- }
-
- public Map getPathConfig() {
- return paths;
- }
-
- private Map configurePaths() {
- ProtectedResource protectedResource = this.authzClient.protection().resource();
- boolean loadPathsFromServer = !enforcerConfig.getLazyLoadPaths();
-
- for (PathConfig pathConfig : enforcerConfig.getPaths()) {
- if (!org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode.DISABLED.equals(pathConfig.getEnforcementMode())) {
- loadPathsFromServer = false;
- break;
- }
- }
-
- if (loadPathsFromServer) {
- LOGGER.info("No path provided in configuration.");
- Map paths = configureAllPathsForResourceServer(protectedResource);
-
- paths.putAll(configureDefinedPaths(protectedResource, enforcerConfig));
-
- return paths;
- } else {
- LOGGER.info("Paths provided in configuration.");
- return configureDefinedPaths(protectedResource, enforcerConfig);
- }
- }
-
- private Map configureDefinedPaths(ProtectedResource protectedResource, PolicyEnforcerConfig enforcerConfig) {
- Map paths = Collections.synchronizedMap(new LinkedHashMap());
-
- for (PathConfig pathConfig : enforcerConfig.getPaths()) {
- ResourceRepresentation resource;
- String resourceName = pathConfig.getName();
- String path = pathConfig.getPath();
-
- if (resourceName != null) {
- LOGGER.debugf("Trying to find resource with name [%s] for path [%s].", resourceName, path);
- resource = protectedResource.findByName(resourceName);
- } else {
- LOGGER.debugf("Trying to find resource with uri [%s] for path [%s].", path, path);
- List resources = protectedResource.findByUri(path);
-
- if (resources.isEmpty()) {
- resources = protectedResource.findByMatchingUri(path);
- }
-
- if (resources.size() == 1) {
- resource = resources.get(0);
- } else if (resources.size() > 1) {
- throw new RuntimeException("Multiple resources found with the same uri");
- } else {
- resource = null;
- }
- }
-
- if (resource != null) {
- pathConfig.setId(resource.getId());
- // if the resource is statically bound to a resource it means the config can not be invalidated
- if (resourceName != null) {
- pathConfig.setStatic(true);
- }
- }
-
- if (org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode.DISABLED.equals(pathConfig.getEnforcementMode())) {
- pathConfig.setStatic(true);
- }
-
- PathConfig existingPath = null;
-
- for (PathConfig current : paths.values()) {
- if (current.getPath().equals(pathConfig.getPath())) {
- existingPath = current;
- break;
- }
- }
-
- if (existingPath == null) {
- paths.put(pathConfig.getPath(), pathConfig);
- } else {
- existingPath.getMethods().addAll(pathConfig.getMethods());
- existingPath.getScopes().addAll(pathConfig.getScopes());
- }
- }
-
- return paths;
- }
-
- private Map configureAllPathsForResourceServer(ProtectedResource protectedResource) {
- LOGGER.info("Querying the server for all resources associated with this application.");
- Map paths = Collections.synchronizedMap(new HashMap());
-
- if (!enforcerConfig.getLazyLoadPaths()) {
- for (String id : protectedResource.findAll()) {
- ResourceRepresentation resourceDescription = protectedResource.findById(id);
-
- if (resourceDescription.getUris() != null && !resourceDescription.getUris().isEmpty()) {
- for(PathConfig pathConfig : PathConfig.createPathConfigs(resourceDescription)) {
- paths.put(pathConfig.getPath(), pathConfig);
- }
- }
- }
- }
-
- return paths;
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java
deleted file mode 100644
index 6c5bc73f89..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.keycloak.adapters.authorization;
-
-import static org.keycloak.adapters.authorization.util.JsonUtils.asAccessToken;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import org.apache.http.client.HttpClient;
-import org.jboss.logging.Logger;
-import org.keycloak.AuthorizationContext;
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.adapters.authorization.spi.HttpResponse;
-import org.keycloak.authorization.client.AuthorizationDeniedException;
-import org.keycloak.authorization.client.AuthzClient;
-import org.keycloak.authorization.client.ClientAuthorizationContext;
-import org.keycloak.authorization.client.Configuration;
-import org.keycloak.authorization.client.resource.PermissionResource;
-import org.keycloak.authorization.client.resource.ProtectionResource;
-import org.keycloak.common.util.Base64;
-import org.keycloak.protocol.oidc.client.authentication.ClientCredentialsProvider;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.AccessToken.Authorization;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.EnforcementMode;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.MethodConfig;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.PathConfig;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig.ScopeEnforcementMode;
-import org.keycloak.representations.idm.authorization.AuthorizationRequest;
-import org.keycloak.representations.idm.authorization.AuthorizationResponse;
-import org.keycloak.representations.idm.authorization.Permission;
-import org.keycloak.representations.idm.authorization.PermissionRequest;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * A Policy Enforcement Point (PEP) that requests and enforces authorization decisions from Keycloak.
- *
- * @author Pedro Igor
- */
-public class PolicyEnforcer {
-
- private static Logger LOGGER = Logger.getLogger(PolicyEnforcer.class);
- private static final String HTTP_METHOD_DELETE = "DELETE";
-
- public static Builder builder() {
- return new Builder();
- }
-
- private final AuthzClient authzClient;
- private final Map paths;
- private final PathConfigMatcher pathMatcher;
- private final HttpClient httpClient;
- private final PolicyEnforcerConfig enforcerConfig;
-
- private final Map claimInformationPointProviderFactories = new HashMap<>();
-
- protected PolicyEnforcer(Builder builder) {
- enforcerConfig = builder.getEnforcerConfig();
- Configuration authzClientConfig = builder.authzClientConfig;
-
- if (authzClientConfig.getRealm() == null) {
- authzClientConfig.setRealm(enforcerConfig.getRealm());
- }
-
- if (authzClientConfig.getAuthServerUrl() == null) {
- authzClientConfig.setAuthServerUrl(enforcerConfig.getAuthServerUrl());
- }
-
- if (authzClientConfig.getCredentials() == null || authzClientConfig.getCredentials().isEmpty()) {
- authzClientConfig.setCredentials(enforcerConfig.getCredentials());
- }
-
- if (authzClientConfig.getResource() == null) {
- authzClientConfig.setResource(enforcerConfig.getResource());
- }
-
- authzClient = AuthzClient.create(authzClientConfig);
- httpClient = authzClient.getConfiguration().getHttpClient();
- pathMatcher = new PathConfigMatcher(builder.getEnforcerConfig(), authzClient);
- paths = pathMatcher.getPathConfig();
-
- loadClaimInformationPointProviders(ServiceLoader.load(ClaimInformationPointProviderFactory.class, ClaimInformationPointProviderFactory.class.getClassLoader()));
- loadClaimInformationPointProviders(ServiceLoader.load(ClaimInformationPointProviderFactory.class, Thread.currentThread().getContextClassLoader()));
- }
-
- public AuthorizationContext enforce(HttpRequest request, HttpResponse response) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugv("Policy enforcement is enabled. Enforcing policy decisions for path [{0}].", request.getURI());
- }
-
- AuthorizationContext context = authorize(request, response);
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugv("Policy enforcement result for path [{0}] is : {1}", request.getURI(), context.isGranted() ? "GRANTED" : "DENIED");
- LOGGER.debugv("Returning authorization context with permissions:");
- for (Permission permission : context.getPermissions()) {
- LOGGER.debug(permission);
- }
- }
-
- return context;
- }
-
- public HttpClient getHttpClient() {
- return httpClient;
- }
-
- public AuthzClient getAuthzClient() {
- return authzClient;
- }
-
- public Map getPaths() {
- return Collections.unmodifiableMap(paths);
- }
-
- public Map getClaimInformationPointProviderFactories() {
- return claimInformationPointProviderFactories;
- }
-
- public PathConfigMatcher getPathMatcher() {
- return pathMatcher;
- }
-
- private AuthorizationContext authorize(HttpRequest request, HttpResponse response) {
- EnforcementMode enforcementMode = enforcerConfig.getEnforcementMode();
- TokenPrincipal principal = request.getPrincipal();
- boolean anonymous = principal == null || principal.getRawToken() == null;
-
- if (EnforcementMode.DISABLED.equals(enforcementMode)) {
- if (anonymous) {
- response.sendError(401, "Invalid bearer");
- }
- return createEmptyAuthorizationContext(true);
- }
-
- PathConfig pathConfig = getPathConfig(request);
-
- if (anonymous) {
- if (!isDefaultAccessDeniedUri(request)) {
- if (pathConfig != null) {
- if (EnforcementMode.DISABLED.equals(pathConfig.getEnforcementMode())) {
- return createEmptyAuthorizationContext(true);
- } else {
- challenge(pathConfig, getRequiredScopes(pathConfig, request), request, response);
- }
- } else {
- handleAccessDenied(response);
- }
- }
- return createEmptyAuthorizationContext(false);
- }
-
- AccessToken accessToken = principal.getToken();
-
- if (accessToken != null) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugf("Checking permissions for path [%s] with config [%s].", request.getURI(), pathConfig);
- }
-
- if (pathConfig == null) {
- if (EnforcementMode.PERMISSIVE.equals(enforcementMode)) {
- return createAuthorizationContext(accessToken, null);
- }
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugf("Could not find a configuration for path [%s]", getPath(request));
- }
-
- if (isDefaultAccessDeniedUri(request)) {
- return createAuthorizationContext(accessToken, null);
- }
-
- handleAccessDenied(response);
-
- return createEmptyAuthorizationContext(false);
- }
-
- if (EnforcementMode.DISABLED.equals(pathConfig.getEnforcementMode())) {
- return createAuthorizationContext(accessToken, pathConfig);
- }
-
- MethodConfig methodConfig = getRequiredScopes(pathConfig, request);
- Map> claims = resolveClaims(pathConfig, request);
-
- if (isAuthorized(pathConfig, methodConfig, accessToken, request, claims)) {
- try {
- return createAuthorizationContext(accessToken, pathConfig);
- } catch (Exception e) {
- throw new RuntimeException("Error processing path [" + pathConfig.getPath() + "].", e);
- }
- }
-
- AccessToken original = accessToken;
-
- accessToken = requestAuthorizationToken(pathConfig, methodConfig, request, claims);
-
- if (accessToken != null) {
- AccessToken.Authorization authorization = original.getAuthorization();
-
- if (authorization == null) {
- authorization = new AccessToken.Authorization();
- authorization.setPermissions(new ArrayList());
- }
-
- AccessToken.Authorization newAuthorization = accessToken.getAuthorization();
-
- if (newAuthorization != null) {
- Collection grantedPermissions = authorization.getPermissions();
- Collection newPermissions = newAuthorization.getPermissions();
-
- for (Permission newPermission : newPermissions) {
- if (!grantedPermissions.contains(newPermission)) {
- grantedPermissions.add(newPermission);
- }
- }
- }
-
- original.setAuthorization(authorization);
-
- if (isAuthorized(pathConfig, methodConfig, accessToken, request, claims)) {
- try {
- return createAuthorizationContext(accessToken, pathConfig);
- } catch (Exception e) {
- throw new RuntimeException("Error processing path [" + pathConfig.getPath() + "].", e);
- }
- }
- }
-
- if (methodConfig != null && ScopeEnforcementMode.DISABLED.equals(methodConfig.getScopesEnforcementMode())) {
- return createEmptyAuthorizationContext(true);
- }
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugf("Sending challenge to the client. Path [%s]", pathConfig);
- }
-
- if (!challenge(pathConfig, methodConfig, request, response)) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugf("Challenge not sent, sending default forbidden response. Path [%s]", pathConfig);
- }
- handleAccessDenied(response);
- }
- }
-
- return createEmptyAuthorizationContext(false);
- }
-
- protected boolean isAuthorized(PathConfig actualPathConfig, MethodConfig methodConfig, AccessToken accessToken, HttpRequest request, Map> claims) {
- if (isDefaultAccessDeniedUri(request)) {
- return true;
- }
-
- Authorization authorization = accessToken.getAuthorization();
-
- if (authorization == null) {
- return false;
- }
-
- boolean hasPermission = false;
- Collection grantedPermissions = authorization.getPermissions();
-
- for (Permission permission : grantedPermissions) {
- if (permission.getResourceId() != null) {
- if (isResourcePermission(actualPathConfig, permission)) {
- hasPermission = true;
-
- if (actualPathConfig.isInstance() && !matchResourcePermission(actualPathConfig, permission)) {
- continue;
- }
-
- if (hasResourceScopePermission(methodConfig, permission)) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugf("Authorization GRANTED for path [%s]. Permissions [%s].", actualPathConfig, grantedPermissions);
- }
- if (HTTP_METHOD_DELETE.equalsIgnoreCase(request.getMethod()) && actualPathConfig.isInstance()) {
- pathMatcher.removeFromCache(getPath(request));
- }
-
- return hasValidClaims(permission, claims);
- }
- }
- } else {
- if (hasResourceScopePermission(methodConfig, permission)) {
- return true;
- }
- }
- }
-
- if (!hasPermission && EnforcementMode.PERMISSIVE.equals(actualPathConfig.getEnforcementMode())) {
- return true;
- }
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debugf("Authorization FAILED for path [%s]. Not enough permissions [%s].", actualPathConfig, grantedPermissions);
- }
-
- return false;
- }
-
- protected Map> resolveClaims(PathConfig pathConfig, HttpRequest request) {
- Map> claims = new HashMap<>();
-
- resolveClaims(claims, enforcerConfig.getClaimInformationPointConfig(), request);
- resolveClaims(claims, pathConfig.getClaimInformationPointConfig(), request);
-
- return claims;
- }
-
- protected boolean challenge(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, HttpRequest request, HttpResponse response) {
- if (isBearerAuthorization(request)) {
- String ticket = getPermissionTicket(pathConfig, methodConfig, authzClient, request);
-
- if (ticket != null) {
- response.setHeader("WWW-Authenticate", new StringBuilder("UMA realm=\"").append(authzClient.getConfiguration().getRealm()).append("\"").append(",as_uri=\"")
- .append(authzClient.getServerConfiguration().getIssuer()).append("\"").append(",ticket=\"").append(ticket).append("\"").toString());
- response.sendError(401);
- } else {
- response.sendError(403);
- }
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Sending challenge");
- }
-
- return true;
- }
-
- handleAccessDenied(response);
-
- return true;
- }
-
- protected void handleAccessDenied(HttpResponse response) {
- String accessDeniedPath = enforcerConfig.getOnDenyRedirectTo();
-
- if (accessDeniedPath != null) {
- response.setHeader("Location", accessDeniedPath);
- response.sendError(302);
- } else {
- response.sendError(403);
- }
- }
-
- private boolean hasValidClaims(Permission permission, Map> claims) {
- Map> grantedClaims = permission.getClaims();
-
- if (grantedClaims != null) {
- if (claims.isEmpty()) {
- return false;
- }
-
- for (Entry> entry : grantedClaims.entrySet()) {
- List requestClaims = claims.get(entry.getKey());
-
- if (requestClaims == null || requestClaims.isEmpty() || !entry.getValue().containsAll(requestClaims)) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- private boolean isDefaultAccessDeniedUri(HttpRequest request) {
- String accessDeniedPath = enforcerConfig.getOnDenyRedirectTo();
- return accessDeniedPath != null && request.getURI().contains(accessDeniedPath);
- }
-
- private boolean hasResourceScopePermission(MethodConfig methodConfig, Permission permission) {
- List requiredScopes = methodConfig.getScopes();
- Set allowedScopes = permission.getScopes();
-
- if (allowedScopes.isEmpty()) {
- return true;
- }
-
- PolicyEnforcerConfig.ScopeEnforcementMode enforcementMode = methodConfig.getScopesEnforcementMode();
-
- if (PolicyEnforcerConfig.ScopeEnforcementMode.ALL.equals(enforcementMode)) {
- return allowedScopes.containsAll(requiredScopes);
- }
-
- if (PolicyEnforcerConfig.ScopeEnforcementMode.ANY.equals(enforcementMode)) {
- for (String requiredScope : requiredScopes) {
- if (allowedScopes.contains(requiredScope)) {
- return true;
- }
- }
- }
-
- return requiredScopes.isEmpty();
- }
-
- private AuthorizationContext createEmptyAuthorizationContext(final boolean granted) {
- return new ClientAuthorizationContext(authzClient) {
- @Override
- public boolean hasPermission(String resourceName, String scopeName) {
- return granted;
- }
-
- @Override
- public boolean hasResourcePermission(String resourceName) {
- return granted;
- }
-
- @Override
- public boolean hasScopePermission(String scopeName) {
- return granted;
- }
-
- @Override
- public List getPermissions() {
- return Collections.EMPTY_LIST;
- }
-
- @Override
- public boolean isGranted() {
- return granted;
- }
- };
- }
-
- private String getPath(HttpRequest request) {
- return request.getRelativePath();
- }
-
- private MethodConfig getRequiredScopes(PathConfig pathConfig, HttpRequest request) {
- String method = request.getMethod();
-
- for (MethodConfig methodConfig : pathConfig.getMethods()) {
- if (methodConfig.getMethod().equals(method)) {
- return methodConfig;
- }
- }
-
- MethodConfig methodConfig = new MethodConfig();
-
- methodConfig.setMethod(request.getMethod());
- List scopes = new ArrayList<>();
-
- if (Boolean.TRUE.equals(enforcerConfig.getHttpMethodAsScope())) {
- scopes.add(request.getMethod());
- } else {
- scopes.addAll(pathConfig.getScopes());
- }
-
- methodConfig.setScopes(scopes);
- methodConfig.setScopesEnforcementMode(PolicyEnforcerConfig.ScopeEnforcementMode.ANY);
-
- return methodConfig;
- }
-
- private AuthorizationContext createAuthorizationContext(AccessToken accessToken, PathConfig pathConfig) {
- return new ClientAuthorizationContext(accessToken, pathConfig, authzClient);
- }
-
- private boolean isResourcePermission(PathConfig actualPathConfig, Permission permission) {
- // first we try a match using resource id
- boolean resourceMatch = matchResourcePermission(actualPathConfig, permission);
-
- // as a fallback, check if the current path is an instance and if so, check if parent's id matches the permission
- if (!resourceMatch && actualPathConfig.isInstance()) {
- resourceMatch = matchResourcePermission(actualPathConfig.getParentConfig(), permission);
- }
-
- return resourceMatch;
- }
-
- private boolean matchResourcePermission(PathConfig actualPathConfig, Permission permission) {
- return permission.getResourceId().equals(actualPathConfig.getId());
- }
-
- private PathConfig getPathConfig(HttpRequest request) {
- return isDefaultAccessDeniedUri(request) ? null : pathMatcher.matches(getPath(request));
- }
-
- private AccessToken requestAuthorizationToken(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, HttpRequest request, Map> claims) {
- if (enforcerConfig.getUserManagedAccess() != null) {
- return null;
- }
-
- try {
- TokenPrincipal principal = request.getPrincipal();
- String accessTokenString = principal.getRawToken();
- AccessToken accessToken = principal.getToken();
- AuthorizationRequest authzRequest = new AuthorizationRequest();
-
- if (isBearerAuthorization(request) || accessToken.getAuthorization() != null) {
- authzRequest.addPermission(pathConfig.getId(), methodConfig.getScopes());
- }
-
- if (!claims.isEmpty()) {
- authzRequest.setClaimTokenFormat("urn:ietf:params:oauth:token-type:jwt");
- authzRequest.setClaimToken(Base64.encodeBytes(JsonSerialization.writeValueAsBytes(claims)));
- }
-
- if (accessToken.getAuthorization() != null) {
- authzRequest.setRpt(accessTokenString);
- }
-
- LOGGER.debug("Obtaining authorization for authenticated user.");
- AuthorizationResponse authzResponse;
-
- if (isBearerAuthorization(request)) {
- authzRequest.setSubjectToken(accessTokenString);
- authzResponse = authzClient.authorization().authorize(authzRequest);
- } else {
- authzResponse = authzClient.authorization(accessTokenString).authorize(authzRequest);
- }
-
- if (authzResponse != null) {
- return asAccessToken(authzResponse.getToken());
- }
- } catch (AuthorizationDeniedException ignore) {
- LOGGER.debug("Authorization denied", ignore);
- } catch (Exception e) {
- LOGGER.debug("Authorization failed", e);
- }
-
- return null;
- }
-
- private String getPermissionTicket(PathConfig pathConfig, MethodConfig methodConfig, AuthzClient authzClient, HttpRequest httpFacade) {
- if (enforcerConfig.getUserManagedAccess() != null) {
- ProtectionResource protection = authzClient.protection();
- PermissionResource permission = protection.permission();
- PermissionRequest permissionRequest = new PermissionRequest();
-
- permissionRequest.setResourceId(pathConfig.getId());
- permissionRequest.setScopes(new HashSet<>(methodConfig.getScopes()));
-
- Map> claims = resolveClaims(pathConfig, httpFacade);
-
- if (!claims.isEmpty()) {
- permissionRequest.setClaims(claims);
- }
-
- return permission.create(permissionRequest).getTicket();
- }
-
- return null;
- }
-
- private boolean isBearerAuthorization(HttpRequest request) {
- List authHeaders = request.getHeaders("Authorization");
-
- if (authHeaders != null) {
- for (String authHeader : authHeaders) {
- String[] split = authHeader.trim().split("\\s+");
- if (split == null || split.length != 2) continue;
- if (!split[0].equalsIgnoreCase("Bearer")) continue;
- return true;
- }
- }
-
- return authzClient.getConfiguration().isBearerOnly();
- }
-
- private void loadClaimInformationPointProviders(ServiceLoader loader) {
- for (ClaimInformationPointProviderFactory factory : loader) {
- factory.init(this);
-
- claimInformationPointProviderFactories.put(factory.getName(), factory);
- }
- }
-
- private void resolveClaims(Map> claims, Map> claimInformationPointConfig, HttpRequest request) {
- if (claimInformationPointConfig != null) {
- for (Entry> claimDef : claimInformationPointConfig.entrySet()) {
- ClaimInformationPointProviderFactory factory = claimInformationPointProviderFactories.get(claimDef.getKey());
-
- if (factory != null) {
- claims.putAll(factory.create(claimDef.getValue()).resolve(request));
- }
- }
- }
- }
-
- public static class Builder {
-
- Configuration authzClientConfig = new Configuration();
-
- private Builder() {
- }
-
- public Builder authServerUrl(String authServerUrl) {
- authzClientConfig.setAuthServerUrl(authServerUrl);
- return this;
- }
-
- public Builder realm(String realm) {
- authzClientConfig.setRealm(realm);
- return this;
- }
-
- public Builder clientId(String clientId) {
- authzClientConfig.setResource(clientId);
- return this;
- }
-
- public Builder bearerOnly(boolean bearerOnly) {
- authzClientConfig.setBearerOnly(bearerOnly);
- return this;
- }
-
- public Builder credentials(Map credentials) {
- authzClientConfig.setCredentials(credentials);
- return this;
- }
-
- public Builder enforcerConfig(PolicyEnforcerConfig enforcerConfig) {
- authzClientConfig.setPolicyEnforcerConfig(enforcerConfig);
- return this;
- }
-
- public Builder enforcerConfig(InputStream is) {
- try {
- enforcerConfig(JsonSerialization.readValue(is, PolicyEnforcerConfig.class));
- } catch (Exception cause) {
- throw new RuntimeException("Failed to read configuration", cause);
- }
- return this;
- }
-
- public Builder httpClient(HttpClient httpClient) {
- authzClientConfig.setHttpClient(httpClient);
- return this;
- }
-
- public Builder credentialProvider(ClientCredentialsProvider credentialsProvider) {
- authzClientConfig.setClientCredentialsProvider(credentialsProvider);
- return this;
- }
-
- public PolicyEnforcer build() {
- return new PolicyEnforcer(this);
- }
-
- PolicyEnforcerConfig getEnforcerConfig() {
- return authzClientConfig.getPolicyEnforcerConfig();
- }
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/TokenPrincipal.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/TokenPrincipal.java
deleted file mode 100644
index d47434382b..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/TokenPrincipal.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization;
-
-import java.security.Principal;
-
-import org.keycloak.adapters.authorization.util.JsonUtils;
-import org.keycloak.representations.AccessToken;
-
-/**
- * A {@link Principal} backed by a token representing the entity requesting permissions.
- *
- * @author Pedro Igor
- */
-public interface TokenPrincipal extends Principal {
-
- /**
- * The token in its raw format.
- *
- * @return the token in its raw format.
- */
- String getRawToken();
-
- /**
- * The {@link AccessToken} representation of {@link TokenPrincipal#getRawToken()}.
- *
- * @return the access token representation
- */
- default AccessToken getToken() {
- return JsonUtils.asAccessToken(getRawToken());
- }
-
- /**
- * The name of the entity represented by the token.
- *
- * @return the name of the principal
- */
- default String getName() {
- return getToken().getPreferredUsername();
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProvider.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProvider.java
deleted file mode 100644
index 00eab06223..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProvider.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.cip;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProvider;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.adapters.authorization.util.PlaceHolders;
-
-/**
- * @author Pedro Igor
- */
-public class ClaimsInformationPointProvider implements ClaimInformationPointProvider {
-
- private final Map config;
-
- public ClaimsInformationPointProvider(Map config) {
- this.config = config;
- }
-
- @Override
- public Map> resolve(HttpRequest request) {
- Map> claims = new HashMap<>();
-
- for (Entry configEntry : config.entrySet()) {
- String claimName = configEntry.getKey();
- Object claimValue = configEntry.getValue();
- List values = new ArrayList<>();
-
- if (claimValue instanceof String) {
- values = getValues(claimValue.toString(), request);
- } else if (claimValue instanceof Collection) {
-
- for (Object value : Collection.class.cast(claimValue)) {
- List resolvedValues = getValues(value.toString(), request);
-
- if (!resolvedValues.isEmpty()) {
- values.addAll(resolvedValues);
- }
- }
- }
-
- if (!values.isEmpty()) {
- claims.put(claimName, values);
- }
- }
-
- return claims;
- }
-
- private List getValues(String value, HttpRequest httpFacade) {
- return PlaceHolders.resolve(value, httpFacade);
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProviderFactory.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProviderFactory.java
deleted file mode 100644
index 7c1d82f0c6..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/ClaimsInformationPointProviderFactory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.cip;
-
-import java.util.Map;
-
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory;
-
-/**
- * @author Pedro Igor
- */
-public class ClaimsInformationPointProviderFactory implements ClaimInformationPointProviderFactory {
-
- @Override
- public String getName() {
- return "claims";
- }
-
- @Override
- public ClaimsInformationPointProvider create(Map config) {
- return new ClaimsInformationPointProvider(config);
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProvider.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProvider.java
deleted file mode 100644
index 958df54779..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProvider.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.cip;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.util.EntityUtils;
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProvider;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.adapters.authorization.util.JsonUtils;
-import org.keycloak.adapters.authorization.util.PlaceHolders;
-import org.keycloak.authorization.client.util.HttpResponseException;
-import org.keycloak.common.util.StreamUtil;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * @author Pedro Igor
- */
-public class HttpClaimInformationPointProvider implements ClaimInformationPointProvider {
-
- private final Map config;
- private final HttpClient httpClient;
-
- public HttpClaimInformationPointProvider(Map config, HttpClient httpClient) {
- this.config = config;
- this.httpClient = httpClient;
- }
-
- @Override
- public Map> resolve(HttpRequest request) {
- try {
- InputStream responseStream = executeRequest(request);
-
- try (InputStream inputStream = new BufferedInputStream(responseStream)) {
- JsonNode jsonNode = JsonSerialization.mapper.readTree(inputStream);
- Map> claims = new HashMap<>();
- Map claimsDef = (Map) config.get("claims");
-
- if (claimsDef == null) {
- Iterator nodeNames = jsonNode.fieldNames();
-
- while (nodeNames.hasNext()) {
- String nodeName = nodeNames.next();
- claims.put(nodeName, JsonUtils.getValues(jsonNode.get(nodeName)));
- }
- } else {
- for (Entry claimDef : claimsDef.entrySet()) {
- List jsonPaths = new ArrayList<>();
-
- if (claimDef.getValue() instanceof Collection) {
- jsonPaths.addAll(Collection.class.cast(claimDef.getValue()));
- } else {
- jsonPaths.add(claimDef.getValue().toString());
- }
-
- List claimValues = new ArrayList<>();
-
- for (String path : jsonPaths) {
- claimValues.addAll(JsonUtils.getValues(jsonNode, path));
- }
-
- claims.put(claimDef.getKey(), claimValues);
- }
- }
-
- return claims;
- }
- } catch (IOException cause) {
- throw new RuntimeException("Could not obtain claims from http claim information point [" + config.get("url") + "] response", cause);
- }
- }
-
- private InputStream executeRequest(HttpRequest request) {
- String method = config.get("method").toString();
-
- if (method == null) {
- method = "GET";
- }
-
- RequestBuilder builder = null;
-
- if ("GET".equalsIgnoreCase(method)) {
- builder = RequestBuilder.get();
- } else {
- builder = RequestBuilder.post();
- }
-
- builder.setUri(config.get("url").toString());
-
- byte[] bytes = new byte[0];
-
- try {
- setParameters(builder, request);
-
- if (config.containsKey("headers")) {
- setHeaders(builder, request);
- }
-
- HttpResponse response = httpClient.execute(builder.build());
- HttpEntity entity = response.getEntity();
-
- if (entity != null) {
- bytes = EntityUtils.toByteArray(entity);
- }
-
- StatusLine statusLine = response.getStatusLine();
- int statusCode = statusLine.getStatusCode();
-
- if (statusCode < 200 || statusCode >= 300) {
- throw new HttpResponseException("Unexpected response from server: " + statusCode + " / " + statusLine.getReasonPhrase(), statusCode, statusLine.getReasonPhrase(), bytes);
- }
-
- return new ByteArrayInputStream(bytes);
- } catch (Exception cause) {
- try {
- throw new RuntimeException("Error executing http method [" + builder + "]. Response : " + StreamUtil.readString(new ByteArrayInputStream(bytes), Charset.forName("UTF-8")), cause);
- } catch (Exception e) {
- throw new RuntimeException("Error executing http method [" + builder + "]", cause);
- }
- }
- }
-
- private void setHeaders(RequestBuilder builder, HttpRequest request) {
- Object headersDef = config.get("headers");
-
- if (headersDef != null) {
- Map headers = Map.class.cast(headersDef);
-
- for (Entry header : headers.entrySet()) {
- Object value = header.getValue();
- List headerValues = new ArrayList<>();
-
- if (value instanceof Collection) {
- Collection values = Collection.class.cast(value);
-
- for (Object item : values) {
- headerValues.addAll(PlaceHolders.resolve(item.toString(), request));
- }
- } else {
- headerValues.addAll(PlaceHolders.resolve(value.toString(), request));
- }
-
- for (String headerValue : headerValues) {
- builder.addHeader(header.getKey(), headerValue);
- }
- }
- }
- }
-
- private void setParameters(RequestBuilder builder, HttpRequest request) {
- Object config = this.config.get("parameters");
-
- if (config != null) {
- Map paramsDef = Map.class.cast(config);
-
- for (Entry paramDef : paramsDef.entrySet()) {
- Object value = paramDef.getValue();
- List paramValues = new ArrayList<>();
-
- if (value instanceof Collection) {
- Collection values = Collection.class.cast(value);
-
- for (Object item : values) {
- paramValues.addAll(PlaceHolders.resolve(item.toString(), request));
- }
- } else {
- paramValues.addAll(PlaceHolders.resolve(value.toString(), request));
- }
-
- for (String paramValue : paramValues) {
- builder.addParameter(paramDef.getKey(), paramValue);
- }
- }
- }
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProviderFactory.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProviderFactory.java
deleted file mode 100644
index 3c9a4ec264..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/HttpClaimInformationPointProviderFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.cip;
-
-import java.util.Map;
-
-import org.keycloak.adapters.authorization.PolicyEnforcer;
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory;
-
-/**
- * @author Pedro Igor
- */
-public class HttpClaimInformationPointProviderFactory implements ClaimInformationPointProviderFactory {
-
- private PolicyEnforcer policyEnforcer;
-
- @Override
- public String getName() {
- return "http";
- }
-
- @Override
- public void init(PolicyEnforcer policyEnforcer) {
- this.policyEnforcer = policyEnforcer;
- }
-
- @Override
- public HttpClaimInformationPointProvider create(Map config) {
- return new HttpClaimInformationPointProvider(config, policyEnforcer.getHttpClient());
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProvider.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProvider.java
deleted file mode 100644
index 43325a8c83..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProvider.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.cip.spi;
-
-import java.util.List;
-import java.util.Map;
-
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-
-/**
- * @author Pedro Igor
- */
-public interface ClaimInformationPointProvider {
-
- Map> resolve(HttpRequest request);
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProviderFactory.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProviderFactory.java
deleted file mode 100644
index f9e1e305a7..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/cip/spi/ClaimInformationPointProviderFactory.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.cip.spi;
-
-import java.util.Map;
-
-import org.keycloak.adapters.authorization.PolicyEnforcer;
-
-/**
- * @author Pedro Igor
- */
-public interface ClaimInformationPointProviderFactory {
-
- String getName();
-
- default void init(PolicyEnforcer policyEnforcer) {
-
- }
-
- C create(Map config);
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java
deleted file mode 100644
index 99c42912e4..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ElytronPolicyEnforcerFilter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.keycloak.adapters.authorization.integration.elytron;
-
-import java.security.Principal;
-
-import jakarta.servlet.http.HttpServletRequest;
-import org.keycloak.adapters.authorization.PolicyEnforcer;
-import org.keycloak.adapters.authorization.integration.jakarta.ServletPolicyEnforcerFilter;
-import org.keycloak.adapters.authorization.spi.ConfigurationResolver;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.wildfly.security.http.oidc.OidcClientConfiguration;
-import org.wildfly.security.http.oidc.OidcPrincipal;
-import org.wildfly.security.http.oidc.RefreshableOidcSecurityContext;
-
-public class ElytronPolicyEnforcerFilter extends ServletPolicyEnforcerFilter {
-
- public ElytronPolicyEnforcerFilter(ConfigurationResolver configResolver) {
- super(configResolver);
- }
-
- @Override
- protected String extractBearerToken(HttpServletRequest request) {
- Principal principal = request.getUserPrincipal();
-
- if (principal == null) {
- return null;
- }
-
- OidcPrincipal oidcPrincipal = (OidcPrincipal) principal;
- RefreshableOidcSecurityContext securityContext = (RefreshableOidcSecurityContext) oidcPrincipal.getOidcSecurityContext();
-
- if (securityContext == null) {
- return null;
- }
-
- return securityContext.getTokenString();
- }
-
- @Override
- protected PolicyEnforcer createPolicyEnforcer(HttpServletRequest servletRequest, PolicyEnforcerConfig enforcerConfig) {
- RefreshableOidcSecurityContext securityContext = (RefreshableOidcSecurityContext) ((OidcPrincipal) servletRequest.getUserPrincipal()).getOidcSecurityContext();
- OidcClientConfiguration configuration = securityContext.getOidcClientConfiguration();
- String authServerUrl = configuration.getAuthServerBaseUrl();
-
- return PolicyEnforcer.builder()
- .authServerUrl(authServerUrl)
- .realm(configuration.getRealm())
- .clientId(configuration.getClientId())
- .credentials(configuration.getResourceCredentials())
- .bearerOnly(false)
- .enforcerConfig(enforcerConfig)
- .httpClient(configuration.getClient()).build();
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java
deleted file mode 100644
index d5bec3b955..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/PolicyEnforcerServletContextListener.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.keycloak.adapters.authorization.integration.elytron;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-import jakarta.servlet.DispatcherType;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.ServletContextEvent;
-import jakarta.servlet.ServletContextListener;
-import jakarta.servlet.annotation.WebListener;
-import org.jboss.logging.Logger;
-import org.keycloak.adapters.authorization.spi.ConfigurationResolver;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * A {@link ServletContextListener} to programmatically configure the {@link ServletContext} in order to
- * enable the policy enforcer.
- *
- * By default, the policy enforcer configuration is loaded from a file at {@code WEB-INF/policy-enforcer.json}.
- *
- * Applications can also dynamically resolve the configuration by implementing the {@link ConfigurationResolver} SPI. For that,
- * make sure to create a {@link META-INF/services/org.keycloak.adapters.authorization.spi.ConfigurationResolver} to register
- * the implementation.
- *
- * @author Pedro Igor
- */
-@WebListener
-public class PolicyEnforcerServletContextListener implements ServletContextListener {
-
- private final Logger logger = Logger.getLogger(getClass());
-
- @Override
- public void contextInitialized(ServletContextEvent sce) {
- ServletContext servletContext = sce.getServletContext();
- Iterator configResolvers = ServiceLoader.load(ConfigurationResolver.class).iterator();
- ConfigurationResolver configResolver;
-
- if (configResolvers.hasNext()) {
- configResolver = configResolvers.next();
-
- if (configResolvers.hasNext()) {
- throw new IllegalStateException("Multiple " + ConfigurationResolver.class.getName() + " implementations found");
- }
-
- logger.debugf("Configuration resolver found from classpath: %s", configResolver);
- } else {
- String enforcerConfigLocation = "WEB-INF/policy-enforcer.json";
- InputStream config = servletContext.getResourceAsStream(enforcerConfigLocation);
-
- if (config == null) {
- logger.debugf("Could not find the policy enforcer configuration file: %s", enforcerConfigLocation);
- return;
- }
-
- try {
- configResolver = createDefaultConfigurationResolver(JsonSerialization.readValue(config, PolicyEnforcerConfig.class));
- } catch (IOException e) {
- throw new RuntimeException("Failed to parse policy enforcer configuration: " + enforcerConfigLocation);
- }
- }
-
- logger.debug("Policy enforcement filter is enabled.");
-
- servletContext.addFilter("keycloak-policy-enforcer", new ElytronPolicyEnforcerFilter(configResolver))
- .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
- }
-
- private ConfigurationResolver createDefaultConfigurationResolver(PolicyEnforcerConfig enforcerConfig) {
- return new ConfigurationResolver() {
- @Override
- public PolicyEnforcerConfig resolve(HttpRequest request) {
- return enforcerConfig;
- }
- };
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java
deleted file mode 100644
index 6b645fce5e..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpRequest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization.integration.elytron;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import jakarta.servlet.http.Cookie;
-import jakarta.servlet.http.HttpServletRequest;
-import org.keycloak.adapters.authorization.TokenPrincipal;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-
-/**
- * @author Pedro Igor
- */
-public class ServletHttpRequest implements HttpRequest {
-
- private final HttpServletRequest request;
- private final TokenPrincipal tokenPrincipal;
- private InputStream inputStream;
-
- public ServletHttpRequest(HttpServletRequest request, TokenPrincipal tokenPrincipal) {
- this.request = request;
- this.tokenPrincipal = tokenPrincipal;
- }
-
- @Override
- public String getRelativePath() {
- String uri = request.getRequestURI();
- String contextPath = request.getContextPath();
- String servletPath = uri.substring(uri.indexOf(contextPath) + contextPath.length());
-
- if ("".equals(servletPath)) {
- servletPath = "/";
- }
-
- return servletPath;
- }
-
- @Override
- public String getMethod() {
- return request.getMethod();
- }
-
- @Override
- public String getURI() {
- return request.getRequestURI();
- }
-
- @Override
- public List getHeaders(String name) {
- return Collections.list(request.getHeaders(name));
- }
-
- @Override
- public String getFirstParam(String name) {
- Map parameters = request.getParameterMap();
- String[] values = parameters.get(name);
-
- if (values == null || values.length == 0) {
- return null;
- }
-
- return values[0];
- }
-
- @Override
- public String getCookieValue(String name) {
- Cookie[] cookies = request.getCookies();
-
- for (Cookie cookie : cookies) {
- if (cookie.getName().equals(name)) {
- return cookie.getValue();
- }
- }
-
- return null;
- }
-
- @Override
- public String getRemoteAddr() {
- return request.getRemoteAddr();
- }
-
- @Override
- public boolean isSecure() {
- return request.isSecure();
- }
-
- @Override
- public String getHeader(String name) {
- return request.getHeader(name);
- }
-
- @Override
- public InputStream getInputStream(boolean buffered) {
- if (inputStream != null) {
- return inputStream;
- }
-
- if (buffered) {
- try {
- return inputStream = new BufferedInputStream(request.getInputStream());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- try {
- return request.getInputStream();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public TokenPrincipal getPrincipal() {
- return tokenPrincipal;
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpResponse.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpResponse.java
deleted file mode 100644
index 9528224790..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/elytron/ServletHttpResponse.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization.integration.elytron;
-
-import java.io.IOException;
-
-import jakarta.servlet.http.HttpServletResponse;
-import org.keycloak.adapters.authorization.spi.HttpResponse;
-
-/**
- * @author Pedro Igor
- */
-public class ServletHttpResponse implements HttpResponse {
-
- private HttpServletResponse response;
-
- public ServletHttpResponse(HttpServletResponse response) {
- this.response = response;
- }
-
- @Override
- public void sendError(int status) {
- try {
- response.sendError(status);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void sendError(int status, String reason) {
- try {
- response.sendError(status, reason);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setHeader(String name, String value) {
- response.setHeader(name, value);
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java
deleted file mode 100644
index ee0931044b..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/integration/jakarta/ServletPolicyEnforcerFilter.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.keycloak.adapters.authorization.integration.jakarta;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-
-import jakarta.servlet.Filter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.FilterConfig;
-import jakarta.servlet.ServletContextAttributeListener;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletResponse;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.HttpSession;
-import org.jboss.logging.Logger;
-import org.keycloak.AuthorizationContext;
-import org.keycloak.adapters.authorization.PolicyEnforcer;
-import org.keycloak.adapters.authorization.TokenPrincipal;
-import org.keycloak.adapters.authorization.integration.elytron.ServletHttpRequest;
-import org.keycloak.adapters.authorization.integration.elytron.ServletHttpResponse;
-import org.keycloak.adapters.authorization.spi.ConfigurationResolver;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.wildfly.security.http.oidc.OidcClientConfiguration;
-import org.wildfly.security.http.oidc.OidcPrincipal;
-import org.wildfly.security.http.oidc.RefreshableOidcSecurityContext;
-
-/**
- * A Jakarta Servlet {@link Filter} acting as a policy enforcer. This filter does not enforce access for anonymous subjects.
- *
- * For authenticated subjects, this filter delegates the access decision to the {@link PolicyEnforcer} and decide if
- * the request should continue.
- *
- * If access is not granted, this filter aborts the request and relies on the {@link PolicyEnforcer} to properly
- * respond to client.
- *
- * @author Pedro Igor
- */
-public class ServletPolicyEnforcerFilter implements Filter, ServletContextAttributeListener {
-
- private final Logger logger = Logger.getLogger(getClass());
- private final Map policyEnforcer;
- private final ConfigurationResolver configResolver;
-
- public ServletPolicyEnforcerFilter(ConfigurationResolver configResolver) {
- this.configResolver = configResolver;
- this.policyEnforcer = Collections.synchronizedMap(new HashMap<>());
- }
-
- @Override
- public void init(FilterConfig filterConfig) {
- // no-init
- }
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- HttpServletRequest request = (HttpServletRequest) servletRequest;
- HttpServletResponse response = (HttpServletResponse) servletResponse;
- ServletHttpRequest httpRequest = new ServletHttpRequest(request, new TokenPrincipal() {
- @Override
- public String getRawToken() {
- return extractBearerToken(request);
- }
- });
-
- PolicyEnforcer policyEnforcer = getOrCreatePolicyEnforcer(request, httpRequest);
- AuthorizationContext authzContext = policyEnforcer.enforce(httpRequest, new ServletHttpResponse(response));
-
- request.setAttribute(AuthorizationContext.class.getName(), authzContext);
-
- if (authzContext.isGranted()) {
- logger.debug("Request authorized, continuing the filter chain");
- filterChain.doFilter(servletRequest, servletResponse);
- } else {
- logger.debugf("Unauthorized request to path [%s], aborting the filter chain", request.getRequestURI());
- }
- }
-
- protected String extractBearerToken(HttpServletRequest request) {
- Enumeration authorizationHeaderValues = request.getHeaders("Authorization");
-
- while (authorizationHeaderValues.hasMoreElements()) {
- String value = authorizationHeaderValues.nextElement();
- String[] parts = value.trim().split("\\s+");
-
- if (parts.length != 2) {
- continue;
- }
-
- String bearer = parts[0];
-
- if (bearer.equalsIgnoreCase("Bearer")) {
- return parts[1];
- }
- }
-
- return null;
- }
-
- private PolicyEnforcer getOrCreatePolicyEnforcer(HttpServletRequest servletRequest, HttpRequest request) {
- return policyEnforcer.computeIfAbsent(configResolver.resolve(request), new Function() {
- @Override
- public PolicyEnforcer apply(PolicyEnforcerConfig enforcerConfig) {
- return createPolicyEnforcer(servletRequest, enforcerConfig);
- }
- });
- }
-
- protected PolicyEnforcer createPolicyEnforcer(HttpServletRequest servletRequest, PolicyEnforcerConfig enforcerConfig) {
- String authServerUrl = enforcerConfig.getAuthServerUrl();
-
- return PolicyEnforcer.builder()
- .authServerUrl(authServerUrl)
- .realm(enforcerConfig.getRealm())
- .clientId(enforcerConfig.getResource())
- .credentials(enforcerConfig.getCredentials())
- .bearerOnly(false)
- .enforcerConfig(enforcerConfig).build();
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/ConfigurationResolver.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/ConfigurationResolver.java
deleted file mode 100644
index 158d3f0922..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/ConfigurationResolver.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization.spi;
-
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-
-/**
- * Resolves a {@link PolicyEnforcerConfig} based on the information from the {@link HttpRequest}.
- *
- * @author Pedro Igor
- */
-public interface ConfigurationResolver {
-
- /**
- * Resolves a {@link PolicyEnforcerConfig} based on the information from the {@link HttpRequest}.
- *
- * @param request the request
- * @return the policy enforcer configuration for the given request
- */
- PolicyEnforcerConfig resolve(HttpRequest request);
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpRequest.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpRequest.java
deleted file mode 100644
index 8fd0722488..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpRequest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization.spi;
-
-import java.io.InputStream;
-import java.util.List;
-
-import org.keycloak.adapters.authorization.TokenPrincipal;
-
-/**
- * Represents an incoming HTTP request and the contract to manipulate it.
- *
- * @author Pedro Igor
- */
-public interface HttpRequest {
-
- /**
- * Get the request path. This is the path relative to the context path.
- * E.g.: for a HTTP GET request to http://my.appserver.com/my-application/path/sub-path this method is going to return /path/sub-path.
-
- * @return the relative path
- */
- String getRelativePath();
-
- /**
- * Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT.
- *
- * @return a {@code String} specifying the name of the method with which this request was made
- */
- String getMethod();
-
- /**
- * Get the URI representation for the current request.
- *
- * @return a {@code String} representation for the current request
- */
- String getURI();
-
- /**
- * Get a list of all of the values set for the specified header within the HTTP request.
- *
- * @param name the header name
- * @return a list of the values set for this header, if the header is not set on the request then null should be returned
- */
- List getHeaders(String name);
-
- /**
- * Get the first value for a parameter with the given {@code name}
- *
- * @param name the parameter name
- * @return the value of the parameter
- */
- String getFirstParam(String name);
-
- /**
- * Get the first value for a cookie with the given {@code name}.
- *
- * @param name the parameter name
- * @return the value of the cookie
- */
- String getCookieValue(String name);
-
- /**
- * Returns the client address.
- *
- * @return the client address.
- */
- String getRemoteAddr();
-
- /**
- * Indicates if the request is coming from a secure channel through HTTPS.
- *
- * @return {@code true} if the HTTP scheme is set to 'https'. Otherwise, {@code false}
- */
- boolean isSecure();
-
- /**
- * Get the first value for a HEADER with the given {@code name}.
- *
- * @param name the HEADER name
- * @return the value of the HEADER
- */
- String getHeader(String name);
-
- /**
- * Returns the request input stream
- *
- * @param buffered if the input stream should be buffered and support for multiple reads
- * @return the request input stream
- */
- InputStream getInputStream(boolean buffered);
-
- /**
- * Returns a {@link TokenPrincipal} associated with the request.
- *
- * @return the principal
- */
- TokenPrincipal getPrincipal();
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpResponse.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpResponse.java
deleted file mode 100644
index dcd41a5f99..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/spi/HttpResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2023 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.adapters.authorization.spi;
-
-/**
- * Represents an outgoing HTTP response and the contract to manipulate it.
- *
- * @author Pedro Igor
- */
-public interface HttpResponse {
-
- /**
- * Send an error with the given {@code statusCode}.
- *
- * @param statusCode the status to set in the response
- */
- void sendError(int statusCode);
-
- /**
- * Send an error with the given {@code statusCode} and {@code reason} message.
- *
- * @param statusCode the status to set in the response
- */
- void sendError(int statusCode, String reason);
-
- /**
- * Set a header with the given {@code name} and {@code value}.
- *
- * @param name the header name
- * @param value the header value
- */
- void setHeader(String name, String value);
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/JsonUtils.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/JsonUtils.java
deleted file mode 100644
index 5c06ca60b2..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/JsonUtils.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.util;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * Utility methods to manipulate JSON data
- *
- * @author Pedro Igor
- */
-public class JsonUtils {
-
- public static List getValues(JsonNode jsonNode, String path) {
- return getValues(jsonNode.at(path));
- }
-
- public static List getValues(JsonNode jsonNode) {
- List values = new ArrayList<>();
-
- if (jsonNode.isArray()) {
- for (JsonNode node : jsonNode) {
- String value;
-
- if (node.isObject()) {
- try {
- value = JsonSerialization.writeValueAsString(node);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- } else {
- value = node.asText();
- }
-
- if (value != null) {
- values.add(value);
- }
- }
- } else {
- String value = jsonNode.asText();
-
- if (value != null) {
- values.add(value);
- }
- }
-
- return values;
- }
-
- public static AccessToken asAccessToken(String rawToken) {
- try {
- return new JWSInput(rawToken).readJsonContent(AccessToken.class);
- } catch (Exception cause) {
- throw new RuntimeException("Failed to decode token", cause);
- }
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/KeycloakSecurityContextPlaceHolderResolver.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/KeycloakSecurityContextPlaceHolderResolver.java
deleted file mode 100644
index b5f824ad9a..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/KeycloakSecurityContextPlaceHolderResolver.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.util;
-
-import static org.keycloak.adapters.authorization.util.PlaceHolders.getParameter;
-
-import java.util.Arrays;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import org.keycloak.adapters.authorization.TokenPrincipal;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * @author Pedro Igor
- */
-public class KeycloakSecurityContextPlaceHolderResolver implements PlaceHolderResolver {
-
- public static final String NAME = "keycloak";
-
- @Override
- public List resolve(String placeHolder, HttpRequest request) {
- String source = placeHolder.substring(placeHolder.indexOf('.') + 1);
- TokenPrincipal principal = request.getPrincipal();
-
- if (source.endsWith("access_token")) {
- return Arrays.asList(principal.getRawToken());
- }
-
- JsonNode jsonNode;
-
- if (source.startsWith("access_token[")) {
- jsonNode = JsonSerialization.mapper.valueToTree(principal.getToken());
- } else {
- throw new RuntimeException("Invalid placeholder [" + placeHolder + "]");
- }
-
- return JsonUtils.getValues(jsonNode, getParameter(source, "Invalid placeholder [" + placeHolder + "]"));
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolderResolver.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolderResolver.java
deleted file mode 100644
index 935fc47db1..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolderResolver.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.util;
-
-import java.util.List;
-
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-
-/**
- * @author Pedro Igor
- */
-public interface PlaceHolderResolver {
-
- List resolve(String placeHolder, HttpRequest httpFacade);
-
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolders.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolders.java
deleted file mode 100644
index d7a4f5f479..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/PlaceHolders.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.util;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-
-/**
- * @author Pedro Igor
- */
-public class PlaceHolders {
-
- private static Map resolvers = new HashMap<>();
-
- static {
- resolvers.put(RequestPlaceHolderResolver.NAME, new RequestPlaceHolderResolver());
- resolvers.put(KeycloakSecurityContextPlaceHolderResolver.NAME, new KeycloakSecurityContextPlaceHolderResolver());
- }
-
- private static Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{(.+?)\\}");
- private static Pattern PLACEHOLDER_PARAM_PATTERN = Pattern.compile("\\[(.+?)\\]");
-
- public static List resolve(String value, HttpRequest httpFacade) {
- Map> placeHolders = parsePlaceHolders(value, httpFacade);
-
- if (!placeHolders.isEmpty()) {
- value = formatPlaceHolder(value);
-
- for (Entry> entry : placeHolders.entrySet()) {
- List values = entry.getValue();
-
- if (values.isEmpty() || values.size() > 1) {
- return values;
- }
-
- value = value.replaceAll(entry.getKey(), values.get(0)).trim();
- }
- }
-
- return Arrays.asList(value);
- }
-
- static String getParameter(String source, String messageIfNotFound) {
- Matcher matcher = PLACEHOLDER_PARAM_PATTERN.matcher(source);
-
- while (matcher.find()) {
- return matcher.group(1).replaceAll("'", "");
- }
-
- if (messageIfNotFound != null) {
- throw new RuntimeException(messageIfNotFound);
- }
-
- return null;
- }
-
- private static Map> parsePlaceHolders(String value, HttpRequest httpFacade) {
- Map> placeHolders = Collections.emptyMap();
- Matcher matcher = PLACEHOLDER_PATTERN.matcher(value);
- boolean found = matcher.find();
-
- if (found) {
- placeHolders = new HashMap<>();
- do {
- String placeHolder = matcher.group(1);
- int resolverNameIdx = placeHolder.indexOf('.');
-
- if (resolverNameIdx == -1) {
- throw new RuntimeException("Invalid placeholder [" + value + "]. Could not find resolver name.");
- }
-
- PlaceHolderResolver resolver = resolvers.get(placeHolder.substring(0, resolverNameIdx));
-
- if (resolver != null) {
- List resolved = resolver.resolve(placeHolder, httpFacade);
-
- if (resolved != null) {
- placeHolders.put(formatPlaceHolder(placeHolder), resolved);
- }
- }
- } while (matcher.find());
- }
-
- return placeHolders;
- }
-
- private static String formatPlaceHolder(String placeHolder) {
- return placeHolder.replaceAll("\\{", "").replace("}", "").replace("[", "").replace("]", "").replace("[", "").replace("]", "");
- }
-}
diff --git a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/RequestPlaceHolderResolver.java b/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/RequestPlaceHolderResolver.java
deleted file mode 100644
index 5d49625e99..0000000000
--- a/authz/policy-enforcer/src/main/java/org/keycloak/adapters/authorization/util/RequestPlaceHolderResolver.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.adapters.authorization.util;
-
-import static org.keycloak.adapters.authorization.util.PlaceHolders.getParameter;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * @author Pedro Igor
- */
-public class RequestPlaceHolderResolver implements PlaceHolderResolver {
-
- static String NAME = "request";
-
- @Override
- public List resolve(String placeHolder, HttpRequest request) {
- String source = placeHolder.substring(placeHolder.indexOf('.') + 1);
-
- if (source.startsWith("parameter")) {
- String parameterName = getParameter(source, "Could not obtain parameter name from placeholder [" + source + "]");
- String parameterValue = request.getFirstParam(parameterName);
-
- if (parameterValue != null) {
- return Arrays.asList(parameterValue);
- }
- } else if (source.startsWith("header")) {
- String headerName = getParameter(source, "Could not obtain header name from placeholder [" + source + "]");
- List headerValue = request.getHeaders(headerName);
-
- if (headerValue != null) {
- return headerValue;
- }
- } else if (source.startsWith("cookie")) {
- String cookieName = getParameter(source, "Could not obtain cookie name from placeholder [" + source + "]");
- String cookieValue = request.getCookieValue(cookieName);
-
- if (cookieValue != null) {
- return Arrays.asList(cookieValue);
- }
- } else if (source.startsWith("remoteAddr")) {
- String value = request.getRemoteAddr();
-
- if (value != null) {
- return Arrays.asList(value);
- }
- } else if (source.startsWith("method")) {
- String value = request.getMethod();
-
- if (value != null) {
- return Arrays.asList(value);
- }
- } else if (source.startsWith("uri")) {
- String value = request.getURI();
-
- if (value != null) {
- return Arrays.asList(value);
- }
- } else if (source.startsWith("relativePath")) {
- String value = request.getRelativePath();
-
- if (value != null) {
- return Arrays.asList(value);
- }
- } else if (source.startsWith("secure")) {
- return Arrays.asList(String.valueOf(request.isSecure()));
- } else if (source.startsWith("body")) {
- String contentType = request.getHeader("Content-Type");
-
- if (contentType == null) {
- contentType = "";
- } else if (contentType.indexOf(';') != -1){
- contentType = contentType.substring(0, contentType.indexOf(';')).trim();
- }
-
- InputStream body = request.getInputStream(true);
-
- try {
- if (body == null || body.available() == 0) {
- return Collections.emptyList();
- }
- } catch (IOException cause) {
- throw new RuntimeException("Failed to check available bytes in request input stream", cause);
- }
-
- if (body.markSupported()) {
- body.mark(0);
- }
-
- List values = new ArrayList<>();
-
- try {
- switch (contentType) {
- case "application/json":
- try {
- JsonNode jsonNode = JsonSerialization.mapper.readTree(new BufferedInputStream(body) {
- @Override
- public void close() {
- // we can't close the stream because it may be used later by the application
- }
- });
- String path = getParameter(source, null);
-
- if (path == null) {
- values.addAll(JsonUtils.getValues(jsonNode));
- } else {
- values.addAll(JsonUtils.getValues(jsonNode, path));
- }
- } catch (IOException cause) {
- throw new RuntimeException("Could not extract claim from request JSON body", cause);
- }
- break;
- default:
- StringBuilder value = new StringBuilder();
- BufferedReader reader = new BufferedReader(new InputStreamReader(body));
-
- try {
- int ch;
-
- while ((ch = reader.read()) != -1) {
- value.append((char) ch);
- }
- } catch (IOException cause) {
- throw new RuntimeException("Could not extract claim from request body", cause);
- }
-
- values.add(value.toString());
- }
- } finally {
- if (body.markSupported()) {
- try {
- body.reset();
- } catch (IOException cause) {
- throw new RuntimeException("Failed to reset request input stream", cause);
- }
- }
- }
-
- return values;
- }
-
- return Collections.emptyList();
- }
-}
diff --git a/authz/policy-enforcer/src/main/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory b/authz/policy-enforcer/src/main/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory
deleted file mode 100644
index f40afedf26..0000000000
--- a/authz/policy-enforcer/src/main/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# * Copyright 2018 Red Hat, Inc. and/or its affiliates
-# * and other contributors as indicated by the @author tags.
-# *
-# * Licensed under the Apache License, Version 2.0 (the "License");
-# * you may not use this file except in compliance with the License.
-# * You may obtain a copy of the License at
-# *
-# * http://www.apache.org/licenses/LICENSE-2.0
-# *
-# * Unless required by applicable law or agreed to in writing, software
-# * distributed under the License is distributed on an "AS IS" BASIS,
-# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# * See the License for the specific language governing permissions and
-# * limitations under the License.
-#
-
-org.keycloak.adapters.authorization.cip.ClaimsInformationPointProviderFactory
-org.keycloak.adapters.authorization.cip.HttpClaimInformationPointProviderFactory
\ No newline at end of file
diff --git a/authz/pom.xml b/authz/pom.xml
index 31224da503..711d68b471 100644
--- a/authz/pom.xml
+++ b/authz/pom.xml
@@ -20,6 +20,5 @@
policy
client
- policy-enforcer
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 65300a6088..5d2d2199fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1052,11 +1052,6 @@
keycloak-authz-policy-common
${project.version}
-
- org.keycloak
- keycloak-policy-enforcer-tests
- ${project.version}
-
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
deleted file mode 100644
index d5bfc3f6ba..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AuthzTestUtils.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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 d3b0120da5..0e49d344ea 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
@@ -23,14 +23,15 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
-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;
@@ -38,6 +39,7 @@ 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;
@@ -60,6 +62,7 @@ import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.RolesBuilder;
import org.keycloak.testsuite.util.UserBuilder;
+import org.keycloak.util.JsonSerialization;
/**
* @author Bill Burke
@@ -308,12 +311,12 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest {
public void testFindByName() {
AuthzClient authzClient = getAuthzClient("default-session-keycloak.json");
ProtectionResource protection = authzClient.protection();
-
+
protection.resource().create(new ResourceRepresentation("Admin Resources"));
protection.resource().create(new ResourceRepresentation("Resource"));
ResourceRepresentation resource = authzClient.protection().resource().findByName("Resource");
-
+
assertEquals("Resource", resource.getName());
ResourceRepresentation adminResource = authzClient.protection().resource().findByName("Admin Resources");
@@ -346,9 +349,12 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest {
}
private AuthzClient getAuthzClient(String adapterConfig) {
- PolicyEnforcer policyEnforcer = PolicyEnforcer.builder().enforcerConfig(getConfigurationStream(adapterConfig)).build();
-
- return policyEnforcer.getAuthzClient();
+ try {
+ Configuration authzClientConfig = JsonSerialization.readValue(getConfigurationStream(adapterConfig), Configuration.class);
+ return AuthzClient.create(authzClientConfig);
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
}
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
deleted file mode 100644
index 71faf82c29..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ClaimInformationPointProviderTest.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.testsuite.authz.admin;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-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.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.TreeNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-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.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-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.authorization.spi.HttpRequest;
-import org.keycloak.jose.jws.JWSBuilder;
-import org.keycloak.representations.AccessToken;
-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;
-
-/**
- * @author Pedro Igor
- */
-public class ClaimInformationPointProviderTest extends AbstractKeycloakTest {
-
- private static Undertow httpService;
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @BeforeClass
- public static void onBeforeClass() {
- httpService = Undertow.builder().addHttpListener(8989, "localhost").setHandler(exchange -> {
- if (exchange.isInIoThread()) {
- try {
- if (exchange.getRelativePath().equals("/post-claim-information-provider")) {
- FormParserFactory parserFactory = FormParserFactory.builder().build();
- FormDataParser parser = parserFactory.createParser(exchange);
- FormData formData = parser.parseBlocking();
-
- 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")
- || !exchange.getRequestHeaders().get("header-b").contains("header-b-value2")
- || !formData.get("param-a").getFirst().getValue().equals("param-a-value1")
- || !formData.get("param-a").getLast().getValue().equals("param-a-value2")
- || !formData.get("param-subject").getFirst().getValue().equals("sub")
- || !formData.get("param-user-name").getFirst().getValue().equals("username")
- || !formData.get("param-other-claims").getFirst().getValue().equals("param-other-claims-value1")
- || !formData.get("param-other-claims").getLast().getValue().equals("param-other-claims-value2")) {
- exchange.setStatusCode(400);
- return;
- }
-
- exchange.setStatusCode(200);
- } else if (exchange.getRelativePath().equals("/get-claim-information-provider")) {
- 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")
- || !exchange.getQueryParameters().get("param-a").contains("param-a-value1")
- || !exchange.getQueryParameters().get("param-a").contains("param-a-value2")
- || !exchange.getQueryParameters().get("param-subject").contains("sub")
- || !exchange.getQueryParameters().get("param-user-name").contains("username")) {
- exchange.setStatusCode(400);
- return;
- }
-
- exchange.setStatusCode(200);
- } else {
- exchange.setStatusCode(404);
- }
- } finally {
- if (exchange.getStatusCode() == 200) {
- try {
- ObjectMapper mapper = JsonSerialization.mapper;
- JsonParser jsonParser = mapper.getFactory().createParser("{\"a\": \"a-value1\", \"b\": \"b-value1\", \"d\": [\"d-value1\", \"d-value2\"]}");
- TreeNode treeNode = mapper.readTree(jsonParser);
- exchange.getResponseSender().send(treeNode.toString());
- } catch (Exception ignore) {
- ignore.printStackTrace();
- }
- }
- exchange.endExchange();
- }
- }
- }).build();
-
- httpService.start();
- }
-
- @AfterClass
- public static void onAfterClass() {
- if (httpService != null) {
- httpService.stop();
- }
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- RealmRepresentation realm = loadRealm(getClass().getResourceAsStream("/authorization-test/test-authz-realm.json"));
- testRealms.add(realm);
- }
-
- private ClaimInformationPointProvider getClaimInformationProviderForPath(String path, String providerName) {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-config-claims-provider.json", true);
- Map providers = policyEnforcer.getClaimInformationPointProviderFactories();
-
- PathConfig pathConfig = policyEnforcer.getPaths().get(path);
-
- assertNotNull(pathConfig);
-
- Map> cipConfig = pathConfig.getClaimInformationPointConfig();
-
- assertNotNull(cipConfig);
-
- ClaimInformationPointProviderFactory factory = providers.get(providerName);
-
- assertNotNull(factory);
-
- Map claimsConfig = cipConfig.get(providerName);
-
- return factory.create(claimsConfig);
- }
-
- @Test
- public void testBasicClaimsInformationPoint() {
- 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));
- assertEquals("cookie-c", claims.get("claim-from-cookie").get(0));
- assertEquals("user-remote-addr", claims.get("claim-from-remoteAddr").get(0));
- assertEquals("GET", claims.get("claim-from-method").get(0));
- assertEquals("/app/request-uri", claims.get("claim-from-uri").get(0));
- assertEquals("/request-relative-path", claims.get("claim-from-relativePath").get(0));
- assertEquals("true", claims.get("claim-from-secure").get(0));
- assertEquals("static value", claims.get("claim-from-static-value").get(0));
- assertEquals("static", claims.get("claim-from-multiple-static-value").get(0));
- assertEquals("value", claims.get("claim-from-multiple-static-value").get(1));
- assertEquals("Test param-other-claims-value1 and parameter-a", claims.get("param-replace-multiple-placeholder").get(0));
- }
-
- @Test
- public void testBodyJsonClaimsInformationPoint() throws Exception {
- Map> headers = new HashMap<>();
-
- headers.put("Content-Type", Arrays.asList("application/json"));
-
- 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);
-
- 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));
- assertEquals("123", claims.get("claim-from-json-body-number").get(0));
- }
-
- @Test
- public void testBodyJsonObjectClaim() throws Exception {
- Map> headers = new HashMap<>();
-
- headers.put("Content-Type", Arrays.asList("application/json"));
-
- ObjectMapper mapper = JsonSerialization.mapper;
- JsonParser parser = mapper.getFactory().createParser("{\"Individual\" : {\n"
- + "\n"
- + " \"Name\": \"John\",\n"
- + "\n"
- + " \"Lastname\": \"Doe\",\n"
- + "\n"
- + " \"individualRoles\" : [ {\n"
- + "\n"
- + " \"roleSpec\": 2342,\n"
- + "\n"
- + " \"roleId\": 4234},\n"
- + "\n"
- + "{\n"
- + "\n"
- + " \"roleSpec\": 4223,\n"
- + "\n"
- + " \"roleId\": 523\n"
- + "\n"
- + " }\n"
- + "\n"
- + " ]\n"
- + "\n"
- + "}}");
- TreeNode treeNode = mapper.readTree(parser);
-
- 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());
- assertEquals("{\"roleSpec\":2342,\"roleId\":4234}", claims.get("individualRoles").get(0));
- assertEquals("{\"roleSpec\":4223,\"roleId\":523}", claims.get("individualRoles").get(1));
-
- headers.put("Content-Type", Arrays.asList("application/json; charset=utf-8"));
-
- 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());
- assertEquals("{\"roleSpec\":2342,\"roleId\":4234}", claims.get("individualRoles").get(0));
- assertEquals("{\"roleSpec\":4223,\"roleId\":523}", claims.get("individualRoles").get(1));
- }
-
- @Test
- public void testBodyClaimsInformationPoint() {
- 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() {
- 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));
- assertEquals("d-value1", claims.get("d").get(0));
- assertEquals("d-value2", claims.get("d").get(1));
-
- assertNull(claims.get("claim-a"));
- assertNull(claims.get("claim-d"));
- assertNull(claims.get("claim-d0"));
- assertNull(claims.get("claim-d-all"));
- }
-
- @Test
- public void testHttpClaimInformationPointProviderWithClaims() {
- 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));
- assertEquals("d-value2", claims.get("claim-d").get(1));
- assertEquals("d-value1", claims.get("claim-d0").get(0));
- assertEquals("d-value1", claims.get("claim-d-all").get(0));
- assertEquals("d-value2", claims.get("claim-d-all").get(1));
-
- assertNull(claims.get("a"));
- assertNull(claims.get("b"));
- assertNull(claims.get("d"));
- }
-
- private static HttpRequest createHttpRequest() {
- return createHttpRequest(new HashMap<>(), null);
- }
-
- 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);
- }
-
- 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;
- }
-
- 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
deleted file mode 100644
index a352def249..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/EnforcerConfigTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.testsuite.authz.admin;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.keycloak.testsuite.ProfileAssume;
-
-import static org.keycloak.common.Profile.Feature.AUTHORIZATION;
-import static org.keycloak.testsuite.utils.io.IOUtil.loadRealm;
-
-/**
- * @author Pedro Igor
- */
-public class EnforcerConfigTest extends AbstractKeycloakTest {
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- RealmRepresentation realm = loadRealm(getClass().getResourceAsStream("/authorization-test/test-authz-realm.json"));
- testRealms.add(realm);
- }
-
- @Test
- public void testMultiplePathsWithSameName() {
- 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());
- }
-
- @Test
- public void testPathConfigClaimInformationPoint() {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-config-path-cip.json", true);
- Map paths = policyEnforcer.getPaths();
-
- assertEquals(1, paths.size());
-
- PathConfig pathConfig = paths.values().iterator().next();
- Map> cipConfig = pathConfig.getClaimInformationPointConfig();
-
- assertEquals(1, cipConfig.size());
-
- Map claims = cipConfig.get("claims");
-
- assertNotNull(claims);
-
- assertEquals(3, claims.size());
- assertEquals("{request.parameter['a']}", claims.get("claim-a"));
- assertEquals("{request.header['b']}", claims.get("claim-b"));
- assertEquals("{request.cookie['c']}", claims.get("claim-c"));
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/MyCustomCIPFactory.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/MyCustomCIPFactory.java
deleted file mode 100644
index 6d603da181..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/MyCustomCIPFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.testsuite.authz.admin;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProvider;
-import org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory;
-import org.keycloak.adapters.authorization.spi.HttpRequest;
-
-public class MyCustomCIPFactory implements ClaimInformationPointProviderFactory {
-
- @Override
- public String getName() {
- return "my-custom-cip";
- }
-
- @Override
- public MyCustomCIP create(Map config) {
- return new MyCustomCIP(config);
- }
-}
-
-class MyCustomCIP implements ClaimInformationPointProvider {
-
- private final Map config;
-
- MyCustomCIP(Map config) {
- this.config = config;
- }
-
- @Override
- public Map> resolve(HttpRequest request) {
- Map> claims = new HashMap<>();
-
- claims.put("resolved-claim", Arrays.asList(config.get("claim-value").toString()));
-
- return claims;
- }
-}
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
deleted file mode 100644
index 6a2f1e7135..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerClaimsTest.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.testsuite.authz.admin;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.common.Profile.Feature.AUTHORIZATION;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.keycloak.AuthorizationContext;
-import org.keycloak.OAuth2Constants;
-import org.keycloak.adapters.authorization.PolicyEnforcer;
-import org.keycloak.admin.client.resource.ClientResource;
-import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.authorization.client.AuthzClient;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.authorization.AuthorizationRequest;
-import org.keycloak.representations.idm.authorization.AuthorizationResponse;
-import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
-import org.keycloak.representations.idm.authorization.Permission;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
-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;
-import org.keycloak.testsuite.util.RoleBuilder;
-import org.keycloak.testsuite.util.RolesBuilder;
-import org.keycloak.testsuite.util.UserBuilder;
-
-/**
- * @author Pedro Igor
- */
-public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest {
-
- protected static final String REALM_NAME = "authz-test";
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- testRealms.add(RealmBuilder.create().name(REALM_NAME)
- .roles(RolesBuilder.create()
- .realmRole(RoleBuilder.create().name("uma_authorization").build())
- .realmRole(RoleBuilder.create().name("uma_protection").build())
- )
- .user(UserBuilder.create().username("marta").password("password")
- .addRoles("uma_authorization", "uma_protection")
- .role("resource-server-test", "uma_protection"))
- .user(UserBuilder.create().username("kolo").password("password"))
- .client(ClientBuilder.create().clientId("resource-server-uma-test")
- .secret("secret")
- .authorizationServicesEnabled(true)
- .redirectUris("http://localhost/resource-server-uma-test")
- .defaultRoles("uma_protection")
- .directAccessGrants())
- .client(ClientBuilder.create().clientId("resource-server-test")
- .secret("secret")
- .authorizationServicesEnabled(true)
- .redirectUris("http://localhost/resource-server-test")
- .defaultRoles("uma_protection")
- .directAccessGrants())
- .client(ClientBuilder.create().clientId("public-client-test")
- .publicClient()
- .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*")
- .directAccessGrants())
- .build());
- }
-
- @Test
- public void testEnforceUMAAccessWithClaimsUsingBearerToken() {
- initAuthorizationSettings(getClientResource("resource-server-uma-test"));
-
- 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 = policyEnforcer.getAuthzClient();
- String token = authzClient.obtainAccessToken("marta", "password").getToken();
-
- headers.put("Authorization", Arrays.asList("Bearer " + token));
-
- 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(testResponse.getHeaders()));
-
- AuthorizationResponse response = authzClient.authorization("marta", "password").authorize(request);
- token = response.getToken();
-
- assertNotNull(token);
-
- 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"));
-
- 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"));
-
- 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"));
-
- context = policyEnforcer.enforce(
- AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null),
- testResponse.clear());
-
- request = new AuthorizationRequest();
-
- request.setTicket(extractTicket(testResponse.getHeaders()));
-
- response = authzClient.authorization("marta", "password").authorize(request);
- token = response.getToken();
-
- context = policyEnforcer.enforce(
- AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", "POST", token, headers, parameters, null),
- testResponse.clear());
- assertTrue(context.isGranted());
-
- 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());
- Permission permission = context.getPermissions().get(0);
-
- assertEquals(parameters.get("withdrawal.amount").get(0), permission.getClaims().get("withdrawal.amount").iterator().next());
- }
-
- @Test
- public void testEnforceEntitlementAccessWithClaimsWithoutBearerToken() {
- initAuthorizationSettings(getClientResource("resource-server-test"));
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-entitlement-claims-test.json", false);
- HashMap> headers = new HashMap<>();
- HashMap> parameters = new HashMap<>();
-
- AuthzClient authzClient = policyEnforcer.getAuthzClient();
- String token = authzClient.obtainAccessToken("marta", "password").getToken();
-
- 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"));
-
- 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);
- assertEquals(parameters.get("withdrawal.amount").get(0), permission.getClaims().get("withdrawal.amount").iterator().next());
-
- parameters.put("withdrawal.amount", Arrays.asList("200"));
-
- 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"));
-
- 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"));
-
- 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 = context.getPermissions().get(0);
- assertEquals(parameters.get("withdrawal.amount").get(0), permission.getClaims().get("withdrawal.amount").iterator().next());
- }
-
- @Test
- public void testEnforceEntitlementAccessWithClaimsWithBearerToken() {
- initAuthorizationSettings(getClientResource("resource-server-test"));
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-entitlement-claims-test.json", false);
- HashMap> headers = new HashMap<>();
- HashMap> parameters = new HashMap<>();
-
- AuthzClient authzClient = policyEnforcer.getAuthzClient();
- String token = authzClient.obtainAccessToken("marta", "password").getToken();
-
- headers.put("Authorization", Arrays.asList("Bearer " + token));
-
- 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"));
-
- 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"));
-
- 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"));
-
- 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"));
-
- context = policyEnforcer.enforce(
- AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null),
- testResponse.clear());
-
- assertTrue(context.isGranted());
- }
-
- @Test
- public void testEnforceEntitlementAccessWithClaimsWithBearerTokenFromPublicClient() {
- initAuthorizationSettings(getClientResource("resource-server-test"));
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-entitlement-claims-test.json", false);
- HashMap> headers = new HashMap<>();
- HashMap> parameters = new HashMap<>();
-
- 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();
-
- headers.put("Authorization", Arrays.asList("Bearer " + token));
-
- 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"));
-
- 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"));
-
- 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"));
-
- 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"));
-
- context = policyEnforcer.enforce(
- AuthzTestUtils.createHttpRequest("/api/bank/account/1/withdrawal", null, token, headers, parameters, null),
- testResponse.clear());
-
- assertTrue(context.isGranted());
- }
-
- private String extractTicket(Map> headers) {
- List wwwAuthenticateHeader = headers.get("WWW-Authenticate");
-
- assertNotNull(wwwAuthenticateHeader);
- assertFalse(wwwAuthenticateHeader.isEmpty());
-
- String wwwAuthenticate = wwwAuthenticateHeader.get(0);
- return wwwAuthenticate.substring(wwwAuthenticate.indexOf("ticket=") + "ticket=\"".length(), wwwAuthenticate.lastIndexOf('"'));
- }
-
- private void initAuthorizationSettings(ClientResource clientResource) {
- if (clientResource.authorization().resources().findByName("Bank Account").isEmpty()) {
- JSPolicyRepresentation policy = new JSPolicyRepresentation();
-
- policy.setName("Withdrawal Limit Policy");
- policy.setType("script-scripts/enforce-withdraw-limit-policy.js");
-
- clientResource.authorization().policies().js().create(policy).close();
-
- createResource(clientResource, "Bank Account", "/api/bank/account/{id}/withdrawal", "withdrawal");
-
- ScopePermissionRepresentation permission = new ScopePermissionRepresentation();
-
- permission.setName("Withdrawal Permission");
- permission.addScope("withdrawal");
- permission.addPolicy(policy.getName());
-
- clientResource.authorization().permissions().scope().create(permission).close();
- }
- }
-
- private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) {
- ResourceRepresentation representation = new ResourceRepresentation();
-
- representation.setName(name);
- representation.setUri(uri);
- representation.setScopes(Arrays.asList(scopes).stream().map(ScopeRepresentation::new).collect(Collectors.toSet()));
-
- try (jakarta.ws.rs.core.Response response = clientResource.authorization().resources().create(representation)) {
-
- representation.setId(response.readEntity(ResourceRepresentation.class).getId());
-
- return representation;
- }
- }
-
- private ClientResource getClientResource(String name) {
- ClientsResource clients = realmsResouce().realm(REALM_NAME).clients();
- ClientRepresentation representation = clients.findByClientId(name).get(0);
- return clients.get(representation.getId());
- }
-}
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
deleted file mode 100644
index 02f16f9e40..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/PolicyEnforcerTest.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright 2018 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.testsuite.authz.admin;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.keycloak.common.Profile.Feature.AUTHORIZATION;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.keycloak.AuthorizationContext;
-import org.keycloak.OAuth2Constants;
-import org.keycloak.adapters.authorization.PolicyEnforcer;
-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.models.utils.KeycloakModelUtils;
-import org.keycloak.representations.adapters.config.PolicyEnforcerConfig;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.authorization.AuthorizationRequest;
-import org.keycloak.representations.idm.authorization.AuthorizationResponse;
-import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
-import org.keycloak.representations.idm.authorization.Permission;
-import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
-import org.keycloak.representations.idm.authorization.ResourceRepresentation;
-import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
-import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
-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;
-import org.keycloak.testsuite.util.RoleBuilder;
-import org.keycloak.testsuite.util.RolesBuilder;
-import org.keycloak.testsuite.util.UserBuilder;
-import org.keycloak.testsuite.util.WaitUtils;
-
-/**
- * @author Pedro Igor
- */
-public class PolicyEnforcerTest extends AbstractKeycloakTest {
-
- private static final String RESOURCE_SERVER_CLIENT_ID = "resource-server-test";
- private static final String REALM_NAME = "authz-test";
-
- @BeforeClass
- public static void enabled() {
- ProfileAssume.assumeFeatureEnabled(AUTHORIZATION);
- }
-
- @Override
- public void addTestRealms(List testRealms) {
- testRealms.add(RealmBuilder.create().name(REALM_NAME)
- .roles(RolesBuilder.create()
- .realmRole(RoleBuilder.create().name("uma_authorization").build())
- .realmRole(RoleBuilder.create().name("uma_protection").build())
- .realmRole(RoleBuilder.create().name("user").build())
- )
- .user(UserBuilder.create().username("marta").password("password")
- .addRoles("uma_authorization", "uma_protection", "user")
- .role("resource-server-test", "uma_protection"))
- .user(UserBuilder.create().username("kolo").password("password"))
- .client(ClientBuilder.create().clientId("resource-server-uma-test")
- .secret("secret")
- .authorizationServicesEnabled(true)
- .redirectUris("http://localhost/resource-server-uma-test")
- .defaultRoles("uma_protection")
- .directAccessGrants())
- .client(ClientBuilder.create().clientId("resource-server-test")
- .secret("secret")
- .authorizationServicesEnabled(true)
- .redirectUris("http://localhost/resource-server-test")
- .defaultRoles("uma_protection")
- .directAccessGrants())
- .client(ClientBuilder.create().clientId("public-client-test")
- .publicClient()
- .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*")
- .directAccessGrants())
- .build());
- }
-
- @Before
- public void onBefore() {
- initAuthorizationSettings(getClientResource(RESOURCE_SERVER_CLIENT_ID));
- }
-
- @Test
- public void testBearerOnlyClientResponse() {
- 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.getStatus());
-
- 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();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), testResponse.clear());
- assertTrue(context.isGranted());
-
- testResponse = new AuthzTestUtils.TestResponse();
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourceb"), testResponse.clear());
- assertFalse(context.isGranted());
- assertEquals(403, testResponse.getStatus());
- }
-
- @Test
- 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.getStatus());
-
- 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();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), testResponse.clear());
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/"), testResponse.clear());
- assertTrue(context.isGranted());
- }
-
- @Test
- public void testResolvingClaimsOnce() {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only-with-cip.json", true);
-
- 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();
-
- 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();
-
- assertTrue(context.isGranted());
- assertEquals("value-claim-a", claims.get("claim-a").iterator().next());
- assertEquals("claim-b", claims.get("claim-b").iterator().next());
- }
-
- @Test
- public void testCustomClaimProvider() {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only-with-cip.json", true);
-
- 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();
-
- AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), new AuthzTestUtils.TestResponse());
- Permission permission = context.getPermissions().get(0);
- Map> claims = permission.getClaims();
-
- assertTrue(context.isGranted());
- assertEquals("test", claims.get("resolved-claim").iterator().next());
- }
-
- @Test
- public void testOnDenyRedirectTo() {
- 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());
- assertEquals(302, response.getStatus());
- List location = response.getHeaders().getOrDefault("Location", Collections.emptyList());
- assertFalse(location.isEmpty());
- assertEquals("/accessDenied", location.get(0));
- }
-
- @Test
- public void testNotAuthenticatedDenyUnmapedPath() {
- 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());
- assertEquals(403, response.getStatus());
- }
-
- @Test
- public void testMappedPathEnforcementModeDisabled() {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-enforce-mode-path.json", true);
-
- AuthzTestUtils.TestResponse response = new AuthzTestUtils.TestResponse();
- AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public"), response);
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourceb"), response.clear());
- assertFalse(context.isGranted());
- assertEquals(403, response.getStatus());
-
- oauth.realm(REALM_NAME);
- oauth.clientId("public-client-test");
- oauth.doLogin("marta", "password");
- String token = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), null).getAccessToken();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourcea", token), response.clear());
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resourceb", token), response.clear());
- assertFalse(context.isGranted());
- assertEquals(403, response.getStatus());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public", token), response.clear());
- assertTrue(context.isGranted());
- }
-
- @Test
- public void testDisabledPathNoCache() {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-path-nocache.json", true);
-
- AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public"), new AuthzTestUtils.TestResponse());
- assertTrue(context.isGranted());
-
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
- ResourceRepresentation resource = clientResource.authorization().resources()
- .findByName("Root").get(0);
-
- clientResource.authorization().resources().resource(resource.getId()).remove();
-
- // first request caches the path and the entry is invalidated due to the lifespan
- 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
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/all-public"), new AuthzTestUtils.TestResponse());
- assertTrue(context.isGranted());
- }
-
- @Test
- public void testLazyLoadedPathIsCached() {
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
- createResource(clientResource, "Static Test Resource", "/api/any-resource/*");
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName("Any Resource Permission");
- permission.addResource("Static Test Resource");
- permission.addPolicy("Always Grant Policy");
-
- clientResource.authorization().permissions().resource().create(permission);
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-path-nocache.json", true);
-
- 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();
-
- AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/any-resource/test", token), new AuthzTestUtils.TestResponse());
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/any-resource/test", token), new AuthzTestUtils.TestResponse());
- assertTrue(context.isGranted());
-
- ResourceRepresentation resource = clientResource.authorization().resources()
- .findByName("Static Test Resource").get(0);
-
- clientResource.authorization().resources().resource(resource.getId()).remove();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/any-resource/test", token), new AuthzTestUtils.TestResponse());
- assertFalse(context.isGranted());
- }
-
- @Test
- public void testEnforcementModeDisabled() {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-disabled-enforce-mode.json", true);
-
- AuthzTestUtils.TestResponse response = new AuthzTestUtils.TestResponse();
- policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource/public"), response);
- assertEquals(401, response.getStatus());
- }
-
- @Test
- public void testMatchHttpVerbsToScopes() {
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
- ResourceRepresentation resource = createResource(clientResource, "Resource With HTTP Scopes", "/api/resource-with-scope");
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName(resource.getName() + " Permission");
- permission.addResource(resource.getName());
- permission.addPolicy("Always Grant Policy");
-
- PermissionsResource permissions = clientResource.authorization().permissions();
- permissions.resource().create(permission).close();
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-match-http-verbs-scopes.json", true);
- 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();
-
- 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.getStatus());
-
- resource.addScope("GET", "POST");
-
- clientResource.authorization().resources().resource(resource.getId()).update(resource);
-
- policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-match-http-verbs-scopes.json", true);
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear());
- assertTrue(context.isGranted());
-
- 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"));
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "PATCH"), testResponse.clear());
- assertFalse(context.isGranted());
-
- ScopePermissionRepresentation postPermission = new ScopePermissionRepresentation();
-
- postPermission.setName("GET permission");
- postPermission.addScope("GET");
- postPermission.addPolicy("Always Deny Policy");
-
- permissions.scope().create(postPermission).close();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear());
- assertFalse(context.isGranted());
-
- postPermission = permissions.scope().findByName(postPermission.getName());
-
- postPermission.addScope("GET");
- postPermission.addPolicy("Always Grant Policy");
-
- permissions.scope().findById(postPermission.getId()).update(postPermission);
-
- AuthzClient authzClient = policyEnforcer.getAuthzClient();
- AuthorizationResponse authorize = authzClient.authorization(token).authorize();
- token = authorize.getToken();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear());
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear());
- assertTrue(context.isGranted());
-
- postPermission = permissions.scope().findByName(postPermission.getName());
- postPermission.addScope("GET");
- postPermission.addPolicy("Always Deny Policy");
- permissions.scope().findById(postPermission.getId()).update(postPermission);
- authorize = authzClient.authorization(token).authorize();
- token = authorize.getToken();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear());
- assertFalse(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear());
- assertTrue(context.isGranted());
-
- postPermission = permissions.scope().findByName(postPermission.getName());
- postPermission.addScope("GET");
- postPermission.addPolicy("Always Grant Policy");
- permissions.scope().findById(postPermission.getId()).update(postPermission);
- authorize = authzClient.authorization(token).authorize();
- token = authorize.getToken();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear());
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear());
- assertTrue(context.isGranted());
-
- postPermission = permissions.scope().findByName(postPermission.getName());
- postPermission.addScope("POST");
- postPermission.addPolicy("Always Deny Policy");
- permissions.scope().findById(postPermission.getId()).update(postPermission);
- AuthorizationRequest request = new AuthorizationRequest();
-
- request.addPermission(null, "GET");
-
- authorize = authzClient.authorization(token).authorize(request);
- token = authorize.getToken();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token), testResponse.clear());
- assertTrue(context.isGranted());
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/resource-with-scope", token, "POST"), testResponse.clear());
- assertFalse(context.isGranted());
- }
-
- @Test
- public void testUsingSubjectToken() {
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
- ResourceRepresentation resource = createResource(clientResource, "Resource Subject Token", "/api/check-subject-token");
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName(resource.getName() + " Permission");
- permission.addResource(resource.getName());
- permission.addPolicy("Only User Policy");
-
- PermissionsResource permissions = clientResource.authorization().permissions();
- permissions.resource().create(permission).close();
-
- 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.getStatus());
-
- 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();
-
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/check-subject-token", token), testResponse.clear());
- assertTrue(context.isGranted());
- }
-
- @Test
- public void testUsingInvalidToken() {
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
- ResourceRepresentation resource = createResource(clientResource, "Resource Subject Invalid Token", "/api/check-subject-token");
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName(resource.getName() + " Permission");
- permission.addResource(resource.getName());
- permission.addPolicy("Only User Policy");
-
- PermissionsResource permissions = clientResource.authorization().permissions();
- permissions.resource().create(permission).close();
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-bearer-only.json", true);
-
- 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();
-
- 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(AuthzTestUtils.createHttpRequest("/api/check-subject-token", token), new AuthzTestUtils.TestResponse());
- assertFalse(context.isGranted());
- }
-
- @Test
- public void testLazyLoadPaths() {
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
-
- for (int i = 0; i < 200; i++) {
- ResourceRepresentation representation = new ResourceRepresentation();
-
- representation.setType("test");
- representation.setName("Resource " + i);
- representation.setUri("/api/" + i);
-
- jakarta.ws.rs.core.Response response = clientResource.authorization().resources().create(representation);
-
- representation.setId(response.readEntity(ResourceRepresentation.class).getId());
-
- response.close();
- }
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName("Test Permission");
- permission.setResourceType("test");
- permission.addPolicy("Only User Policy");
-
- PermissionsResource permissions = clientResource.authorization().permissions();
- permissions.resource().create(permission).close();
-
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-no-lazyload.json", true);
-
- assertEquals(205, policyEnforcer.getPaths().size());
-
- policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-lazyload.json", true);
- assertEquals(0, policyEnforcer.getPathMatcher().getPathCache().size());
- assertEquals(0, policyEnforcer.getPaths().size());
-
- 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();
-
- for (int i = 0; i < 101; i++) {
- policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/" + i, token), new AuthzTestUtils.TestResponse());
- }
-
- assertEquals(101, policyEnforcer.getPathMatcher().getPathCache().size());
-
- for (int i = 101; i < 200; i++) {
- policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/" + i, token), new AuthzTestUtils.TestResponse());
- }
-
- assertEquals(200, policyEnforcer.getPathMatcher().getPathCache().size());
- assertEquals(0, policyEnforcer.getPaths().size());
-
- ResourceRepresentation resource = clientResource.authorization().resources()
- .findByName("Root").get(0);
-
- clientResource.authorization().resources().resource(resource.getId()).remove();
-
- policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-lazyload-with-paths.json", true);
-
- AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api/0", token), new AuthzTestUtils.TestResponse());
-
- assertTrue(context.isGranted());
- }
-
- @Test
- public void testSetMethodConfigs() {
- ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
- ResourceRepresentation representation = new ResourceRepresentation();
-
- representation.setName(KeycloakModelUtils.generateId());
- representation.setUris(Collections.singleton("/api-method/*"));
-
- ResourcesResource resources = clientResource.authorization().resources();
- jakarta.ws.rs.core.Response response = resources.create(representation);
-
- representation.setId(response.readEntity(ResourceRepresentation.class).getId());
-
- response.close();
-
- try {
- PolicyEnforcer policyEnforcer = AuthzTestUtils.createPolicyEnforcer("enforcer-paths-use-method-config.json", true);
-
- oauth.realm(REALM_NAME);
- oauth.clientId("public-client-test");
- oauth.doLogin("marta", "password");
- String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
- OAuthClient.AccessTokenResponse tokeResponse = oauth.doAccessTokenRequest(code, null);
- String token = tokeResponse.getAccessToken();
-
- AuthorizationContext context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api-method/foo", token), new AuthzTestUtils.TestResponse());
-
- // GET is disabled in the config
- assertTrue(context.isGranted());
-
- PolicyEnforcerConfig.PathConfig pathConfig = policyEnforcer.getPaths().get("/api-method/*");
-
- assertNotNull(pathConfig);
- List methods = pathConfig.getMethods();
- assertEquals(1, methods.size());
- assertTrue(PolicyEnforcerConfig.ScopeEnforcementMode.DISABLED.equals(methods.get(0).getScopesEnforcementMode()));
-
- // other verbs should be protected
- context = policyEnforcer.enforce(AuthzTestUtils.createHttpRequest("/api-method/foo", token, "POST"), new AuthzTestUtils.TestResponse());
-
- assertFalse(context.isGranted());
- } finally {
- resources.resource(representation.getId()).remove();
- }
- }
-
- private void initAuthorizationSettings(ClientResource clientResource) {
- if (clientResource.authorization().resources().findByName("Resource A").isEmpty()) {
- JSPolicyRepresentation jsPolicy = new JSPolicyRepresentation();
-
- jsPolicy.setName("Always Grant Policy");
- jsPolicy.setType("script-scripts/default-policy.js");
-
- clientResource.authorization().policies().js().create(jsPolicy).close();
-
- RolePolicyRepresentation rolePolicy = new RolePolicyRepresentation();
-
- rolePolicy.setName("Only User Policy");
- rolePolicy.addRole("user");
-
- clientResource.authorization().policies().role().create(rolePolicy).close();
-
- createResource(clientResource, "Resource A", "/api/resourcea");
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName("Resource A Permission");
- permission.addResource("Resource A");
- permission.addPolicy(jsPolicy.getName());
-
- clientResource.authorization().permissions().resource().create(permission).close();
- }
-
- if (clientResource.authorization().resources().findByName("Resource B").isEmpty()) {
- JSPolicyRepresentation policy = new JSPolicyRepresentation();
-
- policy.setName("Always Deny Policy");
- policy.setType("script-scripts/always-deny-policy.js");
-
- clientResource.authorization().policies().js().create(policy).close();
-
- createResource(clientResource, "Resource B", "/api/resourceb");
-
- ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
-
- permission.setName("Resource B Permission");
- permission.addResource("Resource B");
- permission.addPolicy(policy.getName());
-
- clientResource.authorization().permissions().resource().create(permission).close();
- }
-
- if (clientResource.authorization().resources().findByName("Root").isEmpty()) {
- createResource(clientResource, "Root", "/*");
- }
- }
-
- private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) {
- ResourceRepresentation representation = new ResourceRepresentation();
-
- representation.setName(name);
- representation.setUri(uri);
- representation.setScopes(Arrays.asList(scopes).stream().map(ScopeRepresentation::new).collect(Collectors.toSet()));
-
- jakarta.ws.rs.core.Response response = clientResource.authorization().resources().create(representation);
-
- representation.setId(response.readEntity(ResourceRepresentation.class).getId());
-
- response.close();
-
- return representation;
- }
-
- private ClientResource getClientResource(String name) {
- ClientsResource clients = realmsResouce().realm(REALM_NAME).clients();
- ClientRepresentation representation = clients.findByClientId(name).get(0);
- return clients.get(representation.getId());
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory
deleted file mode 100644
index 8782d98a79..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.cip.spi.ClaimInformationPointProviderFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# * Copyright 2018 Red Hat, Inc. and/or its affiliates
-# * and other contributors as indicated by the @author tags.
-# *
-# * Licensed under the Apache License, Version 2.0 (the "License");
-# * you may not use this file except in compliance with the License.
-# * You may obtain a copy of the License at
-# *
-# * http://www.apache.org/licenses/LICENSE-2.0
-# *
-# * Unless required by applicable law or agreed to in writing, software
-# * distributed under the License is distributed on an "AS IS" BASIS,
-# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# * See the License for the specific language governing permissions and
-# * limitations under the License.
-#
-
-org.keycloak.testsuite.authz.admin.MyCustomCIPFactory
\ No newline at end of file
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
deleted file mode 100644
index 777840f89f..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 6482606925..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- }
-}
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
deleted file mode 100644
index 122bf26b21..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-claims-provider.json
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- "realm": "test-realm-authz",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "test-app-authz",
- "credentials": {
- "secret": "secret"
- },
- "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-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
deleted file mode 100644
index a757ace7e4..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-path-cip.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "realm": "test-realm-authz",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "test-app-authz",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 7cccc8a87b..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-config-paths-same-name.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "realm": "test-realm-authz",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "test-app-authz",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 93793d73a1..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode-path.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 87f21c1963..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-enforce-mode.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 2629d853ab..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-disabled-path-nocache.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "path-cache": {
- "lifespan": 1
- },
- "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"
- }
- ]
-}
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
deleted file mode 100644
index efbdba00d5..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-entitlement-claims-test.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index de2e3f6842..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload-with-paths.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 9de3180bcc..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-lazyload.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 6d67d75452..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-match-http-verbs-scopes.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 6482606925..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-no-lazyload.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- }
-}
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
deleted file mode 100644
index 54d3746b5a..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-on-deny-redirect.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 0038f44ac5..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths-use-method-config.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-test",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index 50e81da9b7..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-paths.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "realm": "authz-test",
- "resource": "resource-server-test",
- "auth-server-url": "http://localhost:8180/auth",
- "credentials": {
- "secret": "secret"
- },
- "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
deleted file mode 100644
index c858956b8c..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-uma-claims-test.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "realm": "authz-test",
- "auth-server-url": "http://localhost:8180/auth",
- "resource": "resource-server-uma-test",
- "credentials": {
- "secret": "secret"
- },
- "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']}"
- }
- }
- }
- ]
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/test-authz-realm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/test-authz-realm.json
deleted file mode 100644
index f19f3262f6..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/test-authz-realm.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "id": "test-realm-authz",
- "realm": "test-realm-authz",
- "enabled": true,
- "sslRequired": "external",
- "requiredCredentials": [ "password" ],
- "users": [
- {
- "username": "service-account-test-app-authz",
- "enabled": true,
- "serviceAccountClientId": "test-app-authz",
- "clientRoles": {
- "test-app-authz" : ["uma_protection"]
- }
- }
- ],
- "clients": [
- {
- "clientId": "test-app-authz",
- "enabled": true,
- "baseUrl": "/test-app-authz",
- "adminUrl": "/test-app-authz",
- "bearerOnly": false,
- "authorizationSettings": {
- "allowRemoteResourceManagement": true,
- "policyEnforcementMode": "ENFORCING",
- "resources": [
- {
- "name": "Product Resource",
- "uri": "/v1/product/*",
- "scopes": [
- {
- "name": "view",
- "name": "create",
- "name": "delete",
- "name": "update"
- }
- ]
- }
- ]
- },
- "redirectUris": [
- "/test-app-authz/*"
- ],
- "secret": "secret"
- }
- ]
-}
diff --git a/testsuite/integration-arquillian/util/pom.xml b/testsuite/integration-arquillian/util/pom.xml
index bbd389bf96..9ac8045694 100644
--- a/testsuite/integration-arquillian/util/pom.xml
+++ b/testsuite/integration-arquillian/util/pom.xml
@@ -95,9 +95,5 @@
org.keycloak
keycloak-adapter-spi
-
- org.keycloak
- keycloak-policy-enforcer-tests
-