From 2c3c0a3dab7a7473392a71840aa1f5f1253d7994 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sun, 12 Jul 2026 13:07:16 +0200 Subject: [PATCH 1/2] Fix matchRole lookup to include group-inherited and composite roles getRoleMembersStream only returns users with the role assigned directly, so exported attributes silently excluded users who have matchRole via group membership. Filter all realm users with hasRole() instead, matching the resolution already used for authRole. --- .../AttributeEndpointsResourceProvider.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java b/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java index 8c17ec3..5070e96 100644 --- a/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java +++ b/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java @@ -2,6 +2,7 @@ package de.ccc.hamburg.keycloak.attribute_endpoints; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -118,7 +119,11 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider .toList(); UserProvider userProvider = session.users(); - Stream users = userProvider.getRoleMembersStream(realm, matchRole); + // getRoleMembersStream only returns users with matchRole assigned directly; it misses + // users who have the role via group membership (incl. parent groups) or composite roles. + // hasRole() resolves the role the same way authUser.hasRole(authRole) does above. + Stream users = userProvider.searchForUserStream(realm, Map.of()) + .filter(user -> user.hasRole(matchRole)); List attribute_list = users .map(user -> { -- 2.51.2 From db302eebb4238566cb3388875a2a41b0235688ab Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 14:13:39 +0200 Subject: [PATCH 2/2] Remove superflous comment --- .../AttributeEndpointsResourceProvider.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java b/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java index 5070e96..bd98b30 100644 --- a/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java +++ b/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java @@ -119,9 +119,6 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider .toList(); UserProvider userProvider = session.users(); - // getRoleMembersStream only returns users with matchRole assigned directly; it misses - // users who have the role via group membership (incl. parent groups) or composite roles. - // hasRole() resolves the role the same way authUser.hasRole(authRole) does above. Stream users = userProvider.searchForUserStream(realm, Map.of()) .filter(user -> user.hasRole(matchRole)); -- 2.51.2