diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java
index 195835c..58f9a08 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/authorization/ResourcePermissionManagementTest.java
@@ -25,6 +25,10 @@ import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.permission.ResourcePermission;
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
+import org.keycloak.authorization.store.PolicyStore;
+import org.keycloak.authorization.store.StoreFactory;
+import org.keycloak.models.ClientModel;
+import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
@@ -34,6 +38,7 @@ import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -327,6 +332,93 @@ public class ResourcePermissionManagementTest extends AbstractPhotozAdminTest {
assertEquals(0, evaluationsUserRole.size());
}
+ @Test
+ public void testResourceAccessWithClientBasedPolicy() throws Exception {
+ ClientModel testClient1 = getClientByClientId("test-client-1");
+ ClientModel testClient2 = getClientByClientId("test-client-2");
+ Policy clientPolicy = createClientPolicy(Collections.singletonList(testClient1));
+
+ PolicyRepresentation newPermission = new PolicyRepresentation();
+
+ newPermission.setName("Client Permission");
+ newPermission.setType("resource");
+
+ HashedMap config = new HashedMap();
+
+ config.put("defaultResourceType", "http://photoz.com/admin");
+ config.put("applyPolicies", JsonSerialization.writeValueAsString(new String[] {clientPolicy.getId()}));
+
+ newPermission.setConfig(config);
+
+ Response response = newPermissionRequest().post(Entity.entity(newPermission, MediaType.APPLICATION_JSON_TYPE));
+
+ assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+
+ PolicyRepresentation permission = response.readEntity(PolicyRepresentation.class);
+
+ onAuthorizationSession(authorizationProvider -> {
+ Policy policyModel = authorizationProvider.getStoreFactory().getPolicyStore().findById(permission.getId());
+
+ assertNotNull(policyModel);
+ assertEquals(permission.getId(), policyModel.getId());
+ assertEquals(newPermission.getName(), policyModel.getName());
+ assertEquals(resourceServer.getId(), policyModel.getResourceServer().getId());
+ });
+
+ Map<String, DefaultEvaluation> evaluations = performEvaluation(
+ Collections.singletonList(new ResourcePermission(adminResource, Collections.emptyList(), resourceServer)),
+ createAccessTokenForClient(testClient1),
+ createClientConnection("127.0.0.1"));
+
+ assertEquals(1, evaluations.size());
+ assertTrue(evaluations.containsKey(clientPolicy.getId()));
+ assertEquals(Effect.PERMIT, evaluations.get(clientPolicy.getId()).getEffect());
+
+ Map<String, DefaultEvaluation> evaluations2 = performEvaluation(
+ Collections.singletonList(new ResourcePermission(adminResource, Collections.emptyList(), resourceServer)),
+ createAccessTokenForClient(testClient2),
+ createClientConnection("127.0.0.1"));
+
+ assertEquals(1, evaluations2.size());
+ assertTrue(evaluations2.containsKey(clientPolicy.getId()));
+ assertEquals(Effect.DENY, evaluations2.get(clientPolicy.getId()).getEffect());
+ }
+
+ private Policy createClientPolicy(List<ClientModel> allowedClients) {
+ return onAuthorizationSession(authorizationProvider -> {
+ StoreFactory storeFactory = authorizationProvider.getStoreFactory();
+ PolicyStore policyStore = storeFactory.getPolicyStore();
+ Policy policy = policyStore.create("Client-Based Policy", "client", resourceServer);
+
+ List<String> clientIds = new ArrayList<>();
+ for (ClientModel client : allowedClients) {
+ clientIds.add(client.getClientId());
+ }
+
+ String[] clients = clientIds.toArray(new String[clientIds.size()]);
+ HashedMap config = new HashedMap();
+
+ try {
+ config.put("clients", JsonSerialization.writeValueAsString(clients));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ policy.setConfig(config);
+
+ return policy;
+ });
+ }
+
+ private AccessToken createAccessTokenForClient(ClientModel client) {
+ AccessToken accessToken = new AccessToken();
+
+ accessToken.setRealmAccess(new AccessToken.Access());
+ accessToken.issuedFor = client.getClientId();
+
+ return accessToken;
+ }
+
private PolicyRepresentation createAlbumResourceTypePermission() throws Exception {
PolicyRepresentation newPermission = new PolicyRepresentation();
diff --git a/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json b/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json
index 340576c..4e300e4 100644
--- a/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json
+++ b/testsuite/integration/src/test/resources/authorization-test/test-photoz-realm.json
@@ -153,6 +153,26 @@
"/confidential-no-service-account/*"
],
"secret": "secret"
+ },
+ {
+ "clientId": "test-client-1",
+ "secret": "secret",
+ "enabled": true,
+ "baseUrl": "test-client-1",
+ "redirectUris": [
+ "/test-client-1/*"
+ ],
+ "webOrigins" : ["*"]
+ },
+ {
+ "clientId": "test-client-2",
+ "secret": "secret",
+ "enabled": true,
+ "baseUrl": "test-client-2",
+ "redirectUris": [
+ "/test-client-2/*"
+ ],
+ "webOrigins" : ["*"]
}
]
}
\ No newline at end of file