From 47288a96439bb3e6db587ea37ceece7e96665320 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Tue, 28 Oct 2025 18:52:51 +0100 Subject: [PATCH] Role mapper should check if an update is needed for the role Closes #43698 Signed-off-by: Alexander Schwartz --- .../saml/mappers/AbstractAttributeToRoleMapper.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/services/src/main/java/org/keycloak/broker/saml/mappers/AbstractAttributeToRoleMapper.java b/services/src/main/java/org/keycloak/broker/saml/mappers/AbstractAttributeToRoleMapper.java index 28e28adc3f8..2e7bb6bfbae 100644 --- a/services/src/main/java/org/keycloak/broker/saml/mappers/AbstractAttributeToRoleMapper.java +++ b/services/src/main/java/org/keycloak/broker/saml/mappers/AbstractAttributeToRoleMapper.java @@ -62,9 +62,15 @@ public abstract class AbstractAttributeToRoleMapper extends AbstractIdentityProv if (!context.hasMapperGrantedRole(roleName)) { if (this.applies(mapperModel, context)) { context.addMapperGrantedRole(roleName); - user.grantRole(role); + if ((!role.isClientRole() && user.getRealmRoleMappingsStream().noneMatch(r -> r.equals(role))) + || (role.isClientRole() && user.getClientRoleMappingsStream(session.clients().getClientById(realm, role.getContainerId())).noneMatch(r -> r.equals(role)))) { + user.grantRole(role); + } } else { - user.deleteRoleMapping(role); + if ((!role.isClientRole() && user.getRealmRoleMappingsStream().anyMatch(r -> r.equals(role))) + || (role.isClientRole() && user.getClientRoleMappingsStream(session.clients().getClientById(realm, role.getContainerId())).anyMatch(r -> r.equals(role)))) { + user.deleteRoleMapping(role); + } } } }