keycloak-uncached
Changes
server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DecisionPermissionCollector.java 8(+7 -1)
Details
diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DecisionPermissionCollector.java b/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DecisionPermissionCollector.java
index ecf2cd3..560769d 100644
--- a/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DecisionPermissionCollector.java
+++ b/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DecisionPermissionCollector.java
@@ -114,7 +114,13 @@ public class DecisionPermissionCollector extends AbstractDecisionCollector {
}
} else {
for (Result.PolicyResult userManagedPermission : userManagedPermissions) {
- grantedScopes.addAll(userManagedPermission.getPolicy().getScopes());
+ Set<Scope> scopes = new HashSet<>(userManagedPermission.getPolicy().getScopes());
+
+ if (!requestedScopes.isEmpty()) {
+ scopes.retainAll(requestedScopes);
+ }
+
+ grantedScopes.addAll(scopes);
}
if (grantedScopes.isEmpty() && !resource.getScopes().isEmpty()) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java
index 6141fbc..798c273 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java
@@ -178,7 +178,7 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
while (iterator.hasNext()) {
Permission permission = iterator.next();
- if (permission.getResourceName().equalsIgnoreCase(expectedResource)) {
+ if (permission.getResourceName().equalsIgnoreCase(expectedResource) || permission.getResourceId().equals(expectedResource)) {
Set<String> scopes = permission.getScopes();
assertEquals(expectedScopes.length, scopes.size());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java
index 1c886b0..d544645 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java
@@ -18,10 +18,12 @@ package org.keycloak.testsuite.authz;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.UUID;
@@ -33,9 +35,11 @@ import org.keycloak.authorization.client.resource.AuthorizationResource;
import org.keycloak.authorization.client.resource.PolicyResource;
import org.keycloak.authorization.client.resource.ProtectionResource;
import org.keycloak.authorization.client.util.HttpResponseException;
+import org.keycloak.representations.AccessToken;
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.Permission;
import org.keycloak.representations.idm.authorization.PermissionRequest;
import org.keycloak.representations.idm.authorization.PermissionResponse;
import org.keycloak.representations.idm.authorization.PermissionTicketRepresentation;
@@ -614,6 +618,74 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest
assertEquals(2, policy.find(null, null, -1, 2).size());
}
+ @Test
+ public void testGrantRequestedScopesOnly() {
+ ResourceRepresentation resource = new ResourceRepresentation();
+
+ resource.setName(UUID.randomUUID().toString());
+ resource.setOwnerManagedAccess(true);
+ resource.setOwner("marta");
+ resource.addScope("view", "delete");
+
+ ProtectionResource protection = getAuthzClient().protection("marta", "password");
+
+ resource = protection.resource().create(resource);
+
+ UmaPermissionRepresentation permission = new UmaPermissionRepresentation();
+
+ permission.setName("Custom User-Managed Permission");
+ permission.addScope("view");
+ permission.addUser("kolo");
+
+ permission = protection.policy(resource.getId()).create(permission);
+
+ AuthorizationRequest request = new AuthorizationRequest();
+
+ request.addPermission(resource.getId(), "view");
+
+ AuthorizationResponse response = getAuthzClient().authorization("kolo", "password").authorize(request);
+ AccessToken rpt = toAccessToken(response.getToken());
+ Collection<Permission> permissions = rpt.getAuthorization().getPermissions();
+
+ assertPermissions(permissions, resource.getId(), "view");
+
+ assertTrue(permissions.isEmpty());
+
+ request = new AuthorizationRequest();
+
+ request.addPermission(resource.getId(), "delete");
+
+ try {
+ getAuthzClient().authorization("kolo", "password").authorize(request);
+ fail("User should not have permission");
+ } catch (Exception e) {
+ assertTrue(AuthorizationDeniedException.class.isInstance(e));
+ }
+
+ request = new AuthorizationRequest();
+
+ request.addPermission(resource.getId(), "delete");
+
+ try {
+ getAuthzClient().authorization("kolo", "password").authorize(request);
+ fail("User should not have permission");
+ } catch (Exception e) {
+ assertTrue(AuthorizationDeniedException.class.isInstance(e));
+ }
+
+ request = new AuthorizationRequest();
+
+ request.addPermission(resource.getId());
+
+ response = getAuthzClient().authorization("kolo", "password").authorize(request);
+ rpt = toAccessToken(response.getToken());
+ permissions = rpt.getAuthorization().getPermissions();
+
+ assertPermissions(permissions, resource.getId(), "view");
+
+ assertTrue(permissions.isEmpty());
+ }
+
private List<PolicyRepresentation> getAssociatedPolicies(UmaPermissionRepresentation permission) {
return getClient(getRealm()).authorization().policies().policy(permission.getId()).associatedPolicies();
}