Dans la version 4.0.3 il existe un défaut sur l'évaluation des attributs dérivés dans le membership, corrigé dans la version 4.0.4. J'avais mis en attente de cette version, la mise en place complète de mon intégration Identité (USER) et Groupe. En fait ce que je souhaitais faire n'est pas possible sans programmation. Voici la réponse de Francesco Chicchiriccò:
Hi,
in [1] you are affirming that the derived attribute "accountName" is defined as
"'adm-'+personId"
where personId is a USER attribute. Moreover, from [3] I guess that accountName is actually a membership attribute: so, a USER attribute but related to the membership of a given group (appAdmin2 in this case).
From mapping [2] I can see the you are referring to it as
groups[appAdmin2].accountName
where, according to
https://syncope.apache.org/docs/4.0/reference-guide.html#mapping
accountName is a group attribute, taken from group appAdmin2.
Hence, we have a USER derived attribute that should be evaluated against a GROUP attribute.
This is not going to work: derived attributes are evaluated in the context of the owning side: USER derived attributes against the owning user, GROUP derived attributes against the owning group, not mixin.
The fix from SYNCOPE-1944 is now evaluating membership derived attributes against membership plain attributes, which was not happening before.
If you are curious to see what is the expected outcome of the fix from SYNCOPE-1944, then you need to take a look at the test case that was added for such a purpose:
https://github.com/apache/syncope/blob/4_0_X/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java#L347-L371
The whole schema and mapping definitions can work as pure configuration up to a certain point: for every further need - including yours. presumably - Syncope is providing hooks to customize the process; if you have special needs, then probably it is best to code a
https://syncope.apache.org/docs/4.0/reference-guide.html#propagationactions
class in Java or Groovy.
En gros, les attributs dérivées s'appliquent aux attributs de même classe et moi je voulais faire un attribut dérivé sur le groupe (GROUP) qui prenait sa source sur l'identité (USER), donc pas possible.
J'ai donc utilisé la voie de la programmation et fait une classe Java qui rempli le rôle attendu:
@SyncopeImplementation(scope = InstanceScope.PER_CONTEXT)
public class AdminPropagationActions implements PropagationActions{
protected static final Logger LOG = LogManager.getLogger(AdminPropagationActions.class);
@Autowired
protected UserDAO userDAO;
@Override
public void before(PropagationTaskInfo taskInfo) {
if (AnyTypeKind.USER != taskInfo.getAnyTypeKind()) {
LOG.warn("N'est pas un objet USER");
return;
}
if (!taskInfo.getObjectClass().is("__ACCOUNT__")) {
LOG.warn("N'est pas un objet de la classe __ACCOUNT__");
return;
}
String login = null;
String key = null;
Attribute oldLogin = null;
if(taskInfo.getPropagationData() != null &&
taskInfo.getPropagationData().getAttributes() != null
&& !taskInfo.getPropagationData().getAttributes().isEmpty()){
for(Attribute attr : taskInfo.getPropagationData().getAttributes()){
if(attr.getName().equals("login")){
login = (String)attr.getValue().get(0);
LOG.info("Trouve login="+login);
oldLogin = attr;
break;
}
}
}
if(login == null){
LOG.warn("Pas trouvé login dans objet de la classe __ACCOUNT__");
return;
}
String personId = login.split("-")[1];
//on récupère la clé de person et on la renvoie vers la ressource ?
LOG.info("taskInfo.getEntityKey="+taskInfo.getEntityKey());
Attribute newLogin = AttributeBuilder.build("login", "adm-"+personId);
try{
taskInfo.getPropagationData().getAttributes().remove(oldLogin);
taskInfo.getPropagationData().getAttributes().add(newLogin);
}catch(Exception ex){
LOG.error("Erreur sur changement propogation ", ex);
}
}
}
Et cela fonctionne comme le prouve (sur parole ;-) cet extrait de log:
Trouve login=usr-titi //provient de ma classe
taskInfo.getEntityKey=019c09c1-32b5-716a-acab-2a402b01ad92 //provient de ma classe
instance='RestAdmin2' Enter: create(ObjectClass: __ACCOUNT__, [Attribute: {Name=projects, Value=[pj3, pj4]}, Attribute: {Name=appName, Value=[appli2]}, Attribute: {Name=__NAME__, Value=[019c09c1-32b5-716a-acab-2a402b01ad92]}, Attribute: {Name=login, Value=[adm-titi]}], null) Method: create
Create script loaded Method: init
Update script loaded Method: init
Delete script loaded Method: init
Search script loaded Method: init
Sync script loaded Method: init
Schema script loaded Method: init
Test script loaded Method: init
Connector net.tirasa.connid.bundles.rest.RESTConnector successfully inited Method: init
instance='RestAdmin2' Enter: create(ObjectClass: __ACCOUNT__, [Attribute: {Name=projects, Value=[pj3, pj4]}, Attribute: {Name=appName, Value=[appli2]}, Attribute: {Name=__NAME__, Value=[019c09c1-32b5-716a-acab-2a402b01ad92]}, Attribute: {Name=login, Value=[adm-titi]}], OperationOptions: {}) Method: create
Object class: __ACCOUNT__ Method: create
Entering CREATE Script Method: invoke
Sending POST to http://admins2:48080/admins/adda with payload {"login":"adm-titi","key":"019c09c1-32b5-716a-acab-2a402b01ad92","appName":"appli2","projects":["pj3","pj4"]} Method: invoke
Create response: 200 {Content-Length=[151], content-type=[application/json], date=[Thu, 29 Jan 2026 12:37:40 GMT], Content-Type=[application/json]} Method: invoke
On voit que l'on part de la valeur de login = usr-titi pour arriver à adm-titi CQFD.
Pour en finir avec ce travail, afin que Syncope fonctionne et en particulier l'interface enduser, il faut absolument qu'une identité dispose d'un compte au moins pour son usage avec Syncope. Par rapport à mon modèle d'intégration c'est une première exception, mais qui reste acceptable (une identité, un compte, un usage). Ensuite pour faire porter la définition et la génération du compte par les groupes, dans ma vision de l'intégration et compte tenu du produit, il faut en passer par la programmation pour définir des identifiants de compte spécifiques.
"C'est peut être un détail pour vous, mais pour moi ça veut beaucoup ..." surtout pour quelqu'un qui travail debout ;-)
En conclusion si on ajoute la multiplication des ressources avec les mapping liés aux noms des groupes et la programmation pour adapter le nom des comptes, cela commence à faire beaucoup de rigidité pour un modèle d'intégration et conduit inévitablement à un manque de réactivité dans la gestion des autorisations.