From ab93d338e2b1e5d6c631bf40a6dd3601f110bdf7 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Mon, 10 Nov 2025 13:41:25 -0300 Subject: [PATCH] The admin roles manage-authorization and view-authorization should have precedence over manage-client when managing authorization settings Closes #43883 Signed-off-by: Pedro Igor --- .../admin/fgap/RealmPermissionsV2.java | 8 +-- .../admin/authz/fgap/RealmRoleAdminTest.java | 71 +++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 tests/base/src/test/java/org/keycloak/tests/admin/authz/fgap/RealmRoleAdminTest.java diff --git a/services/src/main/java/org/keycloak/services/resources/admin/fgap/RealmPermissionsV2.java b/services/src/main/java/org/keycloak/services/resources/admin/fgap/RealmPermissionsV2.java index b3e331df457..008cbc48aee 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/fgap/RealmPermissionsV2.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/fgap/RealmPermissionsV2.java @@ -27,8 +27,8 @@ class RealmPermissionsV2 extends RealmPermissions { @Override public boolean canManageAuthorizationDefault(ResourceServer resourceServer) { - if (resourceServer == null) { - return super.canManageAuthorizationDefault(resourceServer); + if (super.canManageAuthorizationDefault(resourceServer)) { + return true; } return root.clients().canManage(getClient(resourceServer)); @@ -36,8 +36,8 @@ class RealmPermissionsV2 extends RealmPermissions { @Override public boolean canViewAuthorizationDefault(ResourceServer resourceServer) { - if (resourceServer == null) { - return super.canViewAuthorizationDefault(resourceServer); + if (super.canViewAuthorizationDefault(resourceServer)) { + return true; } return root.clients().canView(getClient(resourceServer)); diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/authz/fgap/RealmRoleAdminTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/authz/fgap/RealmRoleAdminTest.java new file mode 100644 index 00000000000..fd708b4e3c8 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/tests/admin/authz/fgap/RealmRoleAdminTest.java @@ -0,0 +1,71 @@ +package org.keycloak.tests.admin.authz.fgap; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import java.util.List; +import java.util.Map; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; +import org.junit.jupiter.api.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.ClientsResource; +import org.keycloak.models.AdminRoles; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.testframework.annotations.InjectAdminClient; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.realm.ClientConfigBuilder; + +@KeycloakIntegrationTest +public class RealmRoleAdminTest extends AbstractPermissionTest { + + @InjectAdminClient(mode = InjectAdminClient.Mode.MANAGED_REALM, client = "myclient", user = "myadmin") + Keycloak realmAdminClient; + + @Test + public void testManageAuthorizationRole() { + UserRepresentation myadmin = realm.admin().users().search("myadmin").get(0); + ClientsResource clientsApi = realm.admin().clients(); + ClientRepresentation realmManagement = clientsApi.findByClientId("realm-management").get(0); + RoleRepresentation manageAuthorizationRole = clientsApi.get(realmManagement.getId()).roles().get(AdminRoles.MANAGE_AUTHORIZATION).toRepresentation(); + RoleRepresentation viewClientsRole = clientsApi.get(realmManagement.getId()).roles().get(AdminRoles.VIEW_CLIENTS).toRepresentation(); + realm.admin().users().get(myadmin.getId()).roles().clientLevel(realmManagement.getId()).add(List.of(manageAuthorizationRole, viewClientsRole)); + + clientsApi.create(ClientConfigBuilder.create() + .clientId("authz-client") + .secret("secret") + .serviceAccountsEnabled(true) + .authorizationServicesEnabled(true) + .build()).close(); + List clients = clientsApi.findByClientId("authz-client"); + assertThat(clients, hasSize(1)); + ClientRepresentation client = clients.get(0); + assertThat(clientsApi.get(client.getId()).authorization().getSettings(), notNullValue()); + + clientsApi = realmAdminClient.realm(realm.getName()).clients(); + clients = clientsApi.findByClientId(client.getClientId()); + assertThat(clients, hasSize(1)); + + clientsApi.get(client.getId()).authorization().getSettings(); + clientsApi.get(client.getId()).authorization().resources().resources(); + clientsApi.get(client.getId()).authorization().policies().policies(); + clientsApi.get(client.getId()).authorization().permissions().scope().findAll(null, null, null, null, null); + clientsApi.get(client.getId()).authorization().permissions().resource().findByName("test"); + + PolicyRepresentation policy = new PolicyRepresentation(); + + policy.setName("User Policy"); + policy.setType("user"); + policy.setConfig(Map.of("users", "[]")); + + try (Response response = clientsApi.get(client.getId()).authorization().policies().create(policy)) { + assertThat(response.getStatus(), is(Status.CREATED.getStatusCode())); + } + } +}