diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java index efd7f157de..e14d501fe7 100644 --- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java +++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/group/GroupPolicyProviderFactory.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -221,6 +221,8 @@ public class GroupPolicyProviderFactory implements PolicyProviderFactory(Arrays.asList(JsonSerialization.readValue(groups, GroupPolicyRepresentation.GroupDefinition[].class))); + return Arrays.stream(JsonSerialization.readValue(groups, GroupPolicyRepresentation.GroupDefinition[].class)) + .sorted() + .collect(Collectors.toCollection(LinkedHashSet::new)); } } diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java index b3f50748ae..f8e69b330e 100644 --- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java +++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java @@ -38,8 +38,10 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * @author Pedro Igor @@ -191,9 +193,10 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory getRoles(String rawRoles, RealmModel realm) { if (rawRoles != null) { try { - Set roles = new HashSet<>(Arrays.asList(JsonSerialization.readValue(rawRoles, RoleDefinition[].class))); - roles.removeIf(definition -> getRole(definition, realm) == null); - return roles; + return Arrays.stream(JsonSerialization.readValue(rawRoles, RoleDefinition[].class)) + .filter(definition -> getRole(definition, realm) != null) + .sorted() + .collect(Collectors.toCollection(LinkedHashSet::new)); } catch (IOException e) { throw new RuntimeException("Could not parse roles from config: [" + rawRoles + "]", e); } diff --git a/core/src/main/java/org/keycloak/representations/idm/authorization/GroupPolicyRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/authorization/GroupPolicyRepresentation.java index d134aa2004..80a9f38d5e 100644 --- a/core/src/main/java/org/keycloak/representations/idm/authorization/GroupPolicyRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/authorization/GroupPolicyRepresentation.java @@ -89,7 +89,7 @@ public class GroupPolicyRepresentation extends AbstractPolicyRepresentation { } } - public static class GroupDefinition { + public static class GroupDefinition implements Comparable { private String id; private String path; @@ -136,5 +136,13 @@ public class GroupPolicyRepresentation extends AbstractPolicyRepresentation { public void setExtendChildren(boolean extendChildren) { this.extendChildren = extendChildren; } + + @Override + public int compareTo(GroupDefinition o) { + if (o.id == null || id == null) { + return 1; + } + return id.compareTo(o.id); + } } } diff --git a/core/src/main/java/org/keycloak/representations/idm/authorization/RolePolicyRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/authorization/RolePolicyRepresentation.java index 623587efdb..858a61fda5 100644 --- a/core/src/main/java/org/keycloak/representations/idm/authorization/RolePolicyRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/authorization/RolePolicyRepresentation.java @@ -67,7 +67,7 @@ public class RolePolicyRepresentation extends AbstractPolicyRepresentation { this.fetchRoles = fetchRoles; } - public static class RoleDefinition { + public static class RoleDefinition implements Comparable { private String id; private boolean required; @@ -96,5 +96,13 @@ public class RolePolicyRepresentation extends AbstractPolicyRepresentation { public void setRequired(boolean required) { this.required = required; } + + @Override + public int compareTo(RoleDefinition o) { + if (id == null || o.id == null) { + return 1; + } + return id.compareTo(o.id); + } } }