Skip to content

Commit

Permalink
Do not grant scopes not granted for resources owned the resource serv…
Browse files Browse the repository at this point in the history
…er itself

Closes keycloak#25057

Signed-off-by: Pedro Igor <[email protected]>
  • Loading branch information
pedroigor committed Mar 20, 2024
1 parent ceed622 commit 2b88388
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import jakarta.ws.rs.HttpMethod;
Expand Down Expand Up @@ -656,7 +657,12 @@ private void resolveResourcePermission(KeycloakAuthorizationRequest request,
ResourcePermission resourcePermission = addPermission(request, resourceServer, authorization,
permissionsToEvaluate, limit,
requestedScopesModel, grantedResource);

if (resourcePermission != null) {
Collection<Scope> permissionScopes = resourcePermission.getScopes();
if (permissionScopes != null) {
permissionScopes.retainAll(scopes);
}
}
// the permission is explicitly granted by the owner, mark this permission as granted so that we don't run the evaluation engine on it
resourcePermission.setGranted(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
Expand Down Expand Up @@ -2415,6 +2417,65 @@ public void testPermissionOrder() throws Exception {
.getScopes().contains("entity:read")));
}

@Test
public void testSameResultRegardlessOPermissionParameterValue() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
ResourceRepresentation resource = new ResourceRepresentation();

resource.setName(KeycloakModelUtils.generateId());
resource.addScope("scope1", "scope2");
resource.setOwnerManagedAccess(true);

try (Response response = authorization.resources().create(resource)) {
resource = response.readEntity(ResourceRepresentation.class);
}

UserPolicyRepresentation policy = new UserPolicyRepresentation();

policy.setName(KeycloakModelUtils.generateId());
policy.addUser("marta");

authorization.policies().user().create(policy).close();

ScopePermissionRepresentation representation = new ScopePermissionRepresentation();

representation.setName(KeycloakModelUtils.generateId());
representation.addScope("scope1");
representation.addPolicy(policy.getName());

authorization.permissions().scope().create(representation).close();

AuthzClient authzClient = getAuthzClient(AUTHZ_CLIENT_CONFIG);
PermissionTicketRepresentation ticket = new PermissionTicketRepresentation();

ticket.setResource(resource.getId());
ticket.setRequesterName("marta");
ticket.setGranted(true);
ticket.setScopeName("scope1");

authzClient.protection().permission().create(ticket);

AuthorizationRequest request = new AuthorizationRequest();
request.addPermission(resource.getId());
AuthorizationResponse response = authzClient.authorization("marta", "password").authorize(request);
AccessToken rpt = toAccessToken(response.getToken());
ResourceRepresentation finalResource = resource;
List<Permission> permissions = rpt.getAuthorization().getPermissions().stream().filter(permission -> permission.getResourceId().equals(finalResource.getId())).collect(Collectors.toList());
assertEquals(1, permissions.size());
assertEquals(1, permissions.get(0).getScopes().size());
assertEquals("scope1", permissions.get(0).getScopes().iterator().next());

request = new AuthorizationRequest();
request.addPermission(resource.getName());
response = authzClient.authorization("marta", "password").authorize(request);
rpt = toAccessToken(response.getToken());
permissions = rpt.getAuthorization().getPermissions().stream().filter(permission -> permission.getResourceId().equals(finalResource.getId())).collect(Collectors.toList());
assertEquals(1, permissions.size());
assertEquals(1, permissions.get(0).getScopes().size());
assertEquals("scope1", permissions.get(0).getScopes().iterator().next());
}

private void testRptRequestWithResourceName(String configFile) {
Metadata metadata = new Metadata();

Expand Down

0 comments on commit 2b88388

Please sign in to comment.