AuthorizationServices should prevent org group ids for group policies

Closes #46050

Signed-off-by: vramik <vramik@redhat.com>
This commit is contained in:
vramik 2026-02-05 14:00:57 +01:00 committed by Pedro Igor
parent 955131b91f
commit f8246504c4
2 changed files with 56 additions and 1 deletions

View file

@ -26,6 +26,8 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.ws.rs.BadRequestException;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
@ -197,7 +199,14 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory<GroupPo
GroupProvider groups = session.groups();
if (definition.getId() != null) {
return realm.getGroupById(definition.getId());
GroupModel group = realm.getGroupById(definition.getId());
// Validate that only REALM groups can be used in authorization policies
if (group != null && GroupModel.Type.ORGANIZATION.equals(group.getType())) {
throw new BadRequestException("Organization groups cannot be used. Only realm groups are allowed.");
}
return group;
}
GroupModel group = null;

View file

@ -22,10 +22,14 @@ import java.util.List;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.OrganizationResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.MemberRepresentation;
import org.keycloak.representations.idm.OrganizationRepresentation;
import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.organization.admin.AbstractOrganizationTest;
@ -274,4 +278,46 @@ public class OrganizationGroupIsolationTest extends AbstractOrganizationTest {
assertThat(results, hasSize(1));
assertThat(results.get(0).getName(), is("Engineering"));
}
@Test
public void testCannotUseOrgGroupInAuthorizationPolicy() {
// Organization groups cannot be used in authorization policies - only realm groups are allowed
OrganizationRepresentation orgRep = createOrganization();
OrganizationResource orgResource = testRealm().organizations().get(orgRep.getId());
// Create organization group
GroupRepresentation orgGroupRep = new GroupRepresentation();
orgGroupRep.setName("Engineering");
String orgGroupId;
try (Response response = orgResource.groups().addTopLevelGroup(orgGroupRep)) {
assertThat(response.getStatus(), is(Status.CREATED.getStatusCode()));
orgGroupId = ApiUtil.getCreatedId(response);
}
// Create a client with authorization services enabled
ClientRepresentation clientRep = new ClientRepresentation();
clientRep.setClientId("test-authz-client");
clientRep.setSecret("secret");
clientRep.setServiceAccountsEnabled(true);
clientRep.setAuthorizationServicesEnabled(true);
clientRep.setPublicClient(false);
String clientId;
try (Response response = testRealm().clients().create(clientRep)) {
clientId = ApiUtil.getCreatedId(response);
}
getCleanup().addCleanup(() -> testRealm().clients().get(clientId).remove());
ClientResource clientResource = testRealm().clients().get(clientId);
// Try to create a group policy using the organization group - should fail
GroupPolicyRepresentation policy = new GroupPolicyRepresentation();
policy.setName("org-group-policy");
policy.addGroup(orgGroupId);
policy.setLogic(Logic.POSITIVE);
try (Response response = clientResource.authorization().policies().group().create(policy)) {
assertThat(response.getStatus(), is(Status.BAD_REQUEST.getStatusCode()));
}
}
}