This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 4_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/4_1_X by this push:
     new 4d2053bdd2 [SYNCOPE-1970] Expiring Implementation caches by OpenJPA 
RemoteCommitListener
4d2053bdd2 is described below

commit 4d2053bdd2d12f5493cd2f860b4586a23ce64794
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Thu Jun 25 16:55:58 2026 +0200

    [SYNCOPE-1970] Expiring Implementation caches by OpenJPA 
RemoteCommitListener
---
 .../syncope/core/logic/AbstractAnyLogic.java       |  3 +-
 .../apache/syncope/core/logic/CommandLogic.java    |  8 ++-
 .../org/apache/syncope/core/logic/SchemaLogic.java |  2 +
 .../DefaultPlainAttrValidationManager.java         |  2 +
 .../jpa/dao/repo/ImplementationRepoExtImpl.java    |  5 +-
 .../ImplementationManagerRemoteCommitListener.java | 71 ++++++++++++++++++++++
 .../jpa/spring/DomainEntityManagerFactoryBean.java | 13 ++--
 .../spring/DomainRoutingEntityManagerFactory.java  |  7 ++-
 .../neo4j/dao/repo/ImplementationRepoExtImpl.java  |  7 ++-
 .../provisioning/java/DefaultMappingManager.java   | 16 +++--
 .../java/data/AttributableDataBinder.java          |  2 +
 .../java/data/ImplementationDataBinderImpl.java    |  5 +-
 .../provisioning/java/data/TaskDataBinderImpl.java |  3 +-
 .../core/provisioning/java/job/LiveSyncJob.java    |  2 +-
 .../provisioning/java/job/MacroJobDelegate.java    |  4 +-
 .../core/provisioning/java/job/TaskJob.java        |  2 +-
 .../provisioning/java/job/report/ReportJob.java    |  1 +
 .../notification/DefaultNotificationManager.java   |  1 +
 .../AbstractPropagationTaskExecutor.java           |  1 +
 .../pushpull/AbstractProvisioningJobDelegate.java  |  3 +-
 .../java/pushpull/AbstractPullExecutor.java        |  5 +-
 .../provisioning/java/pushpull/InboundMatcher.java | 13 ++--
 .../java/pushpull/LiveSyncJobDelegate.java         |  4 +-
 .../java/pushpull/OutboundMatcher.java             |  3 +
 .../java/pushpull/PullJobDelegate.java             | 11 ++--
 .../java/pushpull/PushJobDelegate.java             |  7 ++-
 .../java/pushpull/SinglePullJobDelegate.java       |  3 +-
 .../java/pushpull/SinglePushJobDelegate.java       |  3 +-
 .../pushpull/stream/StreamPullJobDelegate.java     |  3 +-
 .../pushpull/stream/StreamPushJobDelegate.java     |  3 +-
 .../core/provisioning/java/utils/MappingUtils.java |  2 +
 .../implementation/ImplementationManager.java      | 48 +++++++++------
 .../core/spring/policy/DefaultRuleProvider.java    |  3 +
 .../spring/security/DefaultPasswordGenerator.java  |  1 +
 .../spring/implementation/GroovySandboxTest.java   |  3 +-
 .../spring/implementation/PasswordRuleTest.java    |  2 +
 .../syncope/core/logic/oidc/OIDCUserManager.java   |  6 +-
 .../apache/syncope/core/logic/SAML2SP4UILogic.java |  1 +
 .../core/logic/saml2/SAML2SP4UIUserManager.java    |  6 +-
 39 files changed, 217 insertions(+), 68 deletions(-)

diff --git 
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
 
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index b933876ace..00bc9e77c3 100644
--- 
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ 
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -39,6 +39,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 
 abstract class AbstractAnyLogic<TO extends AnyTO, C extends AnyCR, U extends 
AnyUR> extends AbstractLogic<TO> {
 
@@ -72,7 +73,7 @@ abstract class AbstractAnyLogic<TO extends AnyTO, C extends 
AnyCR, U extends Any
         realm.getActions().forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
-                        impl,
+                        AuthContextUtils.getDomain(), impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
             } catch (Exception e) {
diff --git 
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java
 
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java
index 8b128f080c..48e3192802 100644
--- 
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java
+++ 
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/CommandLogic.java
@@ -41,6 +41,7 @@ import 
org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.search.SyncopePage;
 import org.apache.syncope.core.provisioning.api.macro.Command;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -72,7 +73,7 @@ public class CommandLogic extends AbstractLogic<EntityTO> {
                 map(command -> {
                     try {
                         return new CommandTO.Builder(command.getKey()).
-                                
args(ImplementationManager.emptyArgs(command)).build();
+                                
args(ImplementationManager.emptyArgs(AuthContextUtils.getDomain(), 
command)).build();
                     } catch (Exception e) {
                         LOG.error("Could not get arg class for {}", command, 
e);
                         return null;
@@ -92,7 +93,7 @@ public class CommandLogic extends AbstractLogic<EntityTO> {
 
         try {
             return new CommandTO.Builder(impl.getKey()).
-                    args(ImplementationManager.emptyArgs(impl)).build();
+                    
args(ImplementationManager.emptyArgs(AuthContextUtils.getDomain(), 
impl)).build();
         } catch (Exception e) {
             SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.InvalidImplementation);
             sce.getElements().add("Could not build " + impl.getKey());
@@ -109,6 +110,7 @@ public class CommandLogic extends AbstractLogic<EntityTO> {
         Command<CommandArgs> runnable;
         try {
             runnable = (Command<CommandArgs>) ImplementationManager.build(
+                    AuthContextUtils.getDomain(),
                     impl,
                     () -> perContextCommands.get(impl.getKey()),
                     instance -> perContextCommands.put(impl.getKey(), 
instance));
@@ -135,7 +137,7 @@ public class CommandLogic extends AbstractLogic<EntityTO> {
 
         try {
             return runnable.run(command.getArgs() == null
-                    ? ImplementationManager.emptyArgs(impl)
+                    ? 
ImplementationManager.emptyArgs(AuthContextUtils.getDomain(), impl)
                     : command.getArgs()).message();
         } catch (Exception e) {
             LOG.error("While running {} on {}", command.getKey(), 
command.getArgs(), e);
diff --git 
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
 
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
index db052c13e5..8b4a93c89a 100644
--- 
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
+++ 
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
@@ -50,6 +50,7 @@ import 
org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Schema;
 import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -225,6 +226,7 @@ public class SchemaLogic extends 
AbstractTransactionalLogic<SchemaTO> {
 
         try {
             DropdownValueProvider provider = ImplementationManager.build(
+                    AuthContextUtils.getDomain(),
                     schema.getDropdownValueProvider(),
                     () -> 
perContextDropdownValueProviders.get(schema.getDropdownValueProvider().getKey()),
                     instance -> perContextDropdownValueProviders.put(
diff --git 
a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/DefaultPlainAttrValidationManager.java
 
b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/DefaultPlainAttrValidationManager.java
index 7dcf20929c..ca9eb3d0a6 100644
--- 
a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/DefaultPlainAttrValidationManager.java
+++ 
b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/DefaultPlainAttrValidationManager.java
@@ -25,6 +25,7 @@ import 
org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValueValidator
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,6 +44,7 @@ public class DefaultPlainAttrValidationManager implements 
PlainAttrValidationMan
         if (schema.getValidator() != null) {
             try {
                 validator = ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         schema.getValidator(),
                         () -> 
perContextValidators.get(schema.getValidator().getKey()),
                         instance -> 
perContextValidators.put(schema.getValidator().getKey(), instance));
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ImplementationRepoExtImpl.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ImplementationRepoExtImpl.java
index a7fc53f353..b547b92498 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ImplementationRepoExtImpl.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ImplementationRepoExtImpl.java
@@ -28,6 +28,7 @@ import 
org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 
 public class ImplementationRepoExtImpl implements ImplementationRepoExt {
 
@@ -70,7 +71,7 @@ public class ImplementationRepoExtImpl implements 
ImplementationRepoExt {
     public Implementation save(final Implementation implementation) {
         Implementation merged = entityManager.merge(implementation);
 
-        ImplementationManager.purge(merged.getKey());
+        ImplementationManager.purge(AuthContextUtils.getDomain(), 
merged.getKey());
 
         resourceDAO.findByProvisionSorter(merged).
                 forEach(resource -> 
entityCacheDAO.evict(JPAExternalResource.class, resource.getKey()));
@@ -86,6 +87,6 @@ public class ImplementationRepoExtImpl implements 
ImplementationRepoExt {
         }
 
         entityManager.remove(implementation);
-        ImplementationManager.purge(key);
+        ImplementationManager.purge(AuthContextUtils.getDomain(), key);
     }
 }
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/openjpa/ImplementationManagerRemoteCommitListener.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/openjpa/ImplementationManagerRemoteCommitListener.java
new file mode 100644
index 0000000000..b5e8d47b52
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/openjpa/ImplementationManagerRemoteCommitListener.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.openjpa;
+
+import java.io.Serializable;
+import java.util.Collection;
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.util.StringId;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+import org.apache.syncope.core.spring.implementation.ImplementationManager;
+
+/**
+ * Takes care of connectors' Spring beans (un)registration in case HA is set 
up and the actual change is performed by
+ * another node in the OpenJPA cluster.
+ */
+public class ImplementationManagerRemoteCommitListener implements 
RemoteCommitListener, Serializable {
+
+    private static final long serialVersionUID = 5260753255454140460L;
+
+    protected final String domain;
+
+    public ImplementationManagerRemoteCommitListener(final String domain) {
+        this.domain = domain;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void afterCommit(final RemoteCommitEvent event) {
+        if (event.getPayloadType() != RemoteCommitEvent.PAYLOAD_EXTENTS) {
+            ((Collection<Object>) event.getUpdatedObjectIds()).stream().
+                    filter(StringId.class::isInstance).
+                    map(StringId.class::cast).
+                    forEach(id -> {
+                        if 
(JPAImplementation.class.isAssignableFrom(id.getType())) {
+                            ImplementationManager.purge(domain, id.getId());
+                        }
+                    });
+
+            ((Collection<Object>) event.getDeletedObjectIds()).stream().
+                    filter(StringId.class::isInstance).
+                    map(StringId.class::cast).
+                    forEach(id -> {
+                        if 
(JPAImplementation.class.isAssignableFrom(id.getType())) {
+                            ImplementationManager.purge(domain, id.getId());
+                        }
+                    });
+        }
+    }
+
+    @Override
+    public void close() {
+        // nothing to do
+    }
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
index 281e4a1747..5f9db981ef 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
@@ -20,6 +20,9 @@ package org.apache.syncope.core.persistence.jpa.spring;
 
 import jakarta.persistence.EntityManagerFactory;
 import jakarta.persistence.spi.PersistenceUnitInfo;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.openjpa.event.RemoteCommitListener;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
 import 
org.apache.syncope.core.persistence.jpa.openjpa.ConnectorManagerRemoteCommitListener;
 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -32,6 +35,8 @@ public class DomainEntityManagerFactoryBean extends 
LocalContainerEntityManagerF
 
     private static final long serialVersionUID = 49152547930966545L;
 
+    protected final List<RemoteCommitListener> remoteCommitListeners = new 
ArrayList<>();
+
     protected ConnectorManagerRemoteCommitListener 
connectorManagerRemoteCommitListener;
 
     public void setCommonEntityManagerFactoryConf(final 
CommonEntityManagerFactoryConf commonEMFConf) {
@@ -48,10 +53,8 @@ public class DomainEntityManagerFactoryBean extends 
LocalContainerEntityManagerF
         }
     }
 
-    public void setConnectorManagerRemoteCommitListener(
-            final ConnectorManagerRemoteCommitListener 
connectorManagerRemoteCommitListener) {
-
-        this.connectorManagerRemoteCommitListener = 
connectorManagerRemoteCommitListener;
+    public void addRemoteCommitListener(final RemoteCommitListener 
remoteCommitListener) {
+        remoteCommitListeners.add(remoteCommitListener);
     }
 
     @Override
@@ -59,6 +62,6 @@ public class DomainEntityManagerFactoryBean extends 
LocalContainerEntityManagerF
         super.postProcessEntityManagerFactory(emf, pui);
 
         OpenJPAEntityManagerFactorySPI emfspi = 
emf.unwrap(OpenJPAEntityManagerFactorySPI.class);
-        
emfspi.getConfiguration().getRemoteCommitEventManager().addListener(connectorManagerRemoteCommitListener);
+        remoteCommitListeners.forEach(rcl -> 
emfspi.getConfiguration().getRemoteCommitEventManager().addListener(rcl));
     }
 }
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java
index 54fb903b3b..448711ca68 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java
@@ -38,6 +38,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.jpa.PersistenceProperties;
 import 
org.apache.syncope.core.persistence.jpa.openjpa.ConnectorManagerRemoteCommitListener;
+import 
org.apache.syncope.core.persistence.jpa.openjpa.ImplementationManagerRemoteCommitListener;
 import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
@@ -97,8 +98,9 @@ public class DomainRoutingEntityManagerFactory implements 
EntityManagerFactory,
         emf.setDataSource(Objects.requireNonNull((DataSource) 
dataSource.getObject()));
         emf.setJpaVendorAdapter(vendorAdapter);
         emf.setCommonEntityManagerFactoryConf(commonEMFConf);
-        emf.setConnectorManagerRemoteCommitListener(new 
ConnectorManagerRemoteCommitListener(
+        emf.addRemoteCommitListener(new ConnectorManagerRemoteCommitListener(
                 connectorManager, resourceDAO, 
SyncopeConstants.MASTER_DOMAIN));
+        emf.addRemoteCommitListener(new 
ImplementationManagerRemoteCommitListener(SyncopeConstants.MASTER_DOMAIN));
 
         addToJpaPropertyMap(
                 emf,
@@ -128,8 +130,9 @@ public class DomainRoutingEntityManagerFactory implements 
EntityManagerFactory,
         emf.setDataSource(dataSource);
         emf.setJpaVendorAdapter(vendorAdapter);
         emf.setCommonEntityManagerFactoryConf(commonEMFConf);
-        emf.setConnectorManagerRemoteCommitListener(new 
ConnectorManagerRemoteCommitListener(
+        emf.addRemoteCommitListener(new ConnectorManagerRemoteCommitListener(
                 connectorManager, resourceDAO, domain.getKey()));
+        emf.addRemoteCommitListener(new 
ImplementationManagerRemoteCommitListener(domain.getKey()));
 
         addToJpaPropertyMap(emf, vendorAdapter, domain.getDbSchema(), 
domain.getOrm(), metadataFactory);
 
diff --git 
a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ImplementationRepoExtImpl.java
 
b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ImplementationRepoExtImpl.java
index 417579becf..12e75febb7 100644
--- 
a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ImplementationRepoExtImpl.java
+++ 
b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ImplementationRepoExtImpl.java
@@ -40,6 +40,7 @@ import 
org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jPasswordPoli
 import org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jPushPolicy;
 import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.data.neo4j.core.Neo4jClient;
 import org.springframework.data.neo4j.core.Neo4jTemplate;
 import org.springframework.transaction.annotation.Transactional;
@@ -49,7 +50,7 @@ public class ImplementationRepoExtImpl extends AbstractDAO 
implements Implementa
     protected final ExternalResourceDAO resourceDAO;
 
     protected final PolicyDAO policyDAO;
-    
+
     protected final RealmDAO realmDAO;
 
     protected final EntityCacheDAO entityCacheDAO;
@@ -115,7 +116,7 @@ public class ImplementationRepoExtImpl extends AbstractDAO 
implements Implementa
     public Implementation save(final Implementation implementation) {
         Implementation saved = 
neo4jTemplate.save(nodeValidator.validate(implementation));
 
-        ImplementationManager.purge(saved.getKey());
+        ImplementationManager.purge(AuthContextUtils.getDomain(), 
saved.getKey());
 
         cache.put(EntityCacheKey.of(saved.getKey()), (Neo4jImplementation) 
saved);
 
@@ -151,7 +152,7 @@ public class ImplementationRepoExtImpl extends AbstractDAO 
implements Implementa
 
             neo4jTemplate.deleteById(key, Neo4jImplementation.class);
 
-            ImplementationManager.purge(key);
+            ImplementationManager.purge(AuthContextUtils.getDomain(), key);
         });
     }
 }
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java
index 18889cba91..7986348794 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java
@@ -83,6 +83,7 @@ import 
org.apache.syncope.core.provisioning.api.jexl.JexlContextBuilder;
 import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
 import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.FrameworkUtil;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
@@ -851,7 +852,9 @@ public class DefaultMappingManager implements 
MappingManager {
 
         IntValues transformed = new IntValues(schemaType, values);
         if (transform) {
-            for (ItemTransformer transformer : 
MappingUtils.getItemTransformers(item, getTransformers(item))) {
+            for (ItemTransformer transformer
+                    : 
MappingUtils.getItemTransformers(AuthContextUtils.getDomain(), item, 
getTransformers(item))) {
+
                 transformed = transformer.beforePropagation(
                         item, any, transformed.attrSchemaType(), 
transformed.values());
             }
@@ -930,7 +933,9 @@ public class DefaultMappingManager implements 
MappingManager {
 
         IntValues transformed = new IntValues(schemaType, values);
         if (transform) {
-            for (ItemTransformer transformer : 
MappingUtils.getItemTransformers(item, getTransformers(item))) {
+            for (ItemTransformer transformer
+                    : 
MappingUtils.getItemTransformers(AuthContextUtils.getDomain(), item, 
getTransformers(item))) {
+
                 transformed = transformer.beforePropagation(
                         item, realm, transformed.attrSchemaType(), 
transformed.values());
             }
@@ -1038,7 +1043,8 @@ public class DefaultMappingManager implements 
MappingManager {
         List<Object> values = null;
         if (attr != null) {
             values = attr.getValue();
-            for (ItemTransformer transformer : 
MappingUtils.getItemTransformers(item, getTransformers(item))) {
+            for (ItemTransformer transformer
+                    : 
MappingUtils.getItemTransformers(AuthContextUtils.getDomain(), item, 
getTransformers(item))) {
                 values = transformer.beforePull(item, anyTO, values);
             }
         }
@@ -1163,7 +1169,9 @@ public class DefaultMappingManager implements 
MappingManager {
         List<Object> values = null;
         if (attr != null) {
             values = attr.getValue();
-            for (ItemTransformer transformer : 
MappingUtils.getItemTransformers(item, getTransformers(item))) {
+            for (ItemTransformer transformer
+                    : 
MappingUtils.getItemTransformers(AuthContextUtils.getDomain(), item, 
getTransformers(item))) {
+
                 values = transformer.beforePull(item, realmTO, values);
             }
         }
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
index 8480cade31..b4bdcf2f85 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
@@ -41,6 +41,7 @@ import 
org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -144,6 +145,7 @@ abstract class AttributableDataBinder {
                             List<String> dropdownValues = List.of();
                             try {
                                 DropdownValueProvider provider = 
ImplementationManager.build(
+                                        AuthContextUtils.getDomain(),
                                         schema.getDropdownValueProvider(),
                                         () -> dropdownValueProviders.get(
                                                 
schema.getDropdownValueProvider().getKey()),
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
index 36027f13ce..16544b6cbb 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ImplementationDataBinderImpl.java
@@ -35,6 +35,7 @@ import 
org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.provisioning.api.data.ImplementationDataBinder;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -128,7 +129,7 @@ public class ImplementationDataBinderImpl implements 
ImplementationDataBinder {
 
         Class<?> clazz = null;
         try {
-            clazz = ImplementationManager.getClass(implementation).getLeft();
+            clazz = 
ImplementationManager.getClass(AuthContextUtils.getDomain(), 
implementation).getLeft();
         } catch (Exception e) {
             LOG.error("Could not get Class", e);
             sce.getElements().add("No " + implementation.getKey() + " class 
found");
@@ -146,7 +147,7 @@ public class ImplementationDataBinderImpl implements 
ImplementationDataBinder {
 
         if (implementation.getEngine() == ImplementationEngine.GROOVY) {
             try {
-                ImplementationManager.build(implementation);
+                ImplementationManager.build(AuthContextUtils.getDomain(), 
implementation);
             } catch (Exception e) {
                 LOG.error("While building Groovy class {}", 
implementation.getKey(), e);
 
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index b015989cfe..df5be8b3bb 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -306,7 +306,7 @@ public class TaskDataBinderImpl extends 
AbstractExecutableDatabinder implements
                     try {
                         CommandArgs args = command.getArgs();
                         if (args == null) {
-                            args = ImplementationManager.emptyArgs(impl);
+                            args = 
ImplementationManager.emptyArgs(AuthContextUtils.getDomain(), impl);
                         }
 
                         MacroTaskCommand macroTaskCommand = 
entityFactory.newEntity(MacroTaskCommand.class);
@@ -677,6 +677,7 @@ public class TaskDataBinderImpl extends 
AbstractExecutableDatabinder implements
         } else {
             try {
                 actions = Optional.of(ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         task.getMacroActions(),
                         () -> 
perContextMacroActions.get(task.getMacroActions().getKey()),
                         instance -> 
perContextMacroActions.put(task.getMacroActions().getKey(), instance)));
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/LiveSyncJob.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/LiveSyncJob.java
index 9f51e0a4a2..5a64eda427 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/LiveSyncJob.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/LiveSyncJob.java
@@ -49,7 +49,7 @@ public class LiveSyncJob extends TaskJob {
         if (impl == null) {
             LOG.error("Could not find Implementation '{}', aborting", implKey);
         } else {
-            delegate = ImplementationManager.build(impl);
+            delegate = ImplementationManager.build(context.getDomain(), impl);
             delegate.execute(
                     TaskType.LIVE_SYNC,
                     taskKey,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java
index 98b6f636f3..ba2e801c4f 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java
@@ -274,6 +274,7 @@ public class MacroJobDelegate extends 
AbstractSchedTaskJobDelegate<MacroTask> im
         } else {
             try {
                 actions = Optional.of(ImplementationManager.build(
+                        context.getDomain(),
                         task.getMacroActions(),
                         () -> 
perContextActions.get(task.getMacroActions().getKey()),
                         instance -> 
perContextActions.put(task.getMacroActions().getKey(), instance)));
@@ -296,6 +297,7 @@ public class MacroJobDelegate extends 
AbstractSchedTaskJobDelegate<MacroTask> im
             Command<CommandArgs> runnable;
             try {
                 runnable = (Command<CommandArgs>) ImplementationManager.build(
+                        context.getDomain(),
                         command.getCommand(),
                         () -> 
perContextCommands.get(command.getCommand().getKey()),
                         instance -> 
perContextCommands.put(command.getCommand().getKey(), instance));
@@ -306,7 +308,7 @@ public class MacroJobDelegate extends 
AbstractSchedTaskJobDelegate<MacroTask> im
             CommandArgs args;
             if (command.getArgs() == null) {
                 try {
-                    args = 
ImplementationManager.emptyArgs(command.getCommand());
+                    args = 
ImplementationManager.emptyArgs(context.getDomain(), command.getCommand());
                 } catch (Exception e) {
                     throw new JobExecutionException("While getting empty args 
from " + command.getKey(), e);
                 }
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
index e945c3ea74..0a78a73684 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -67,7 +67,7 @@ public class TaskJob extends Job {
         if (impl == null) {
             LOG.error("Could not find Implementation '{}', aborting", implKey);
         } else {
-            delegate = ImplementationManager.build(impl);
+            delegate = ImplementationManager.build(context.getDomain(), impl);
             delegate.execute(
                     (TaskType) context.getData().get(JobManager.TASK_TYPE),
                     taskKey,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
index 31c9de5041..f6932af1b0 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java
@@ -75,6 +75,7 @@ public class ReportJob extends Job {
             LOG.error("Could not find Implementation '{}', aborting", implKey);
         } else {
             delegate = ImplementationManager.buildReportJobDelegate(
+                    context.getDomain(),
                     impl,
                     () -> perContextReportJobDelegates.get(impl.getKey()),
                     instance -> 
perContextReportJobDelegates.put(impl.getKey(), instance)).
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
index 7ea87dfd13..37acf4efe3 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
@@ -218,6 +218,7 @@ public class DefaultNotificationManager implements 
NotificationManager {
         
Optional.ofNullable(notification.getRecipientsProvider()).ifPresent(impl -> {
             try {
                 RecipientsProvider recipientsProvider = 
ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextRecipientsProvider.orElse(null),
                         instance -> perContextRecipientsProvider = 
Optional.of(instance));
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 69a28f7737..d96c56d33b 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -172,6 +172,7 @@ public abstract class AbstractPropagationTaskExecutor 
implements PropagationTask
         resource.getPropagationActions().forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java
index 1328b35122..bd61bdb24c 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java
@@ -113,10 +113,11 @@ public abstract class AbstractProvisioningJobDelegate<T 
extends ProvisioningTask
                 || task.getResource().getProvisioningTraceLevel().ordinal() >= 
TraceLevel.SUMMARY.ordinal();
     }
 
-    protected ProvisionSorter getProvisionSorter(final T task) {
+    protected ProvisionSorter getProvisionSorter(final String domain, final T 
task) {
         if (task.getResource().getProvisionSorter() != null) {
             try {
                 return ImplementationManager.build(
+                        domain,
                         task.getResource().getProvisionSorter(),
                         () -> perContextProvisionSorter.orElse(null),
                         instance -> perContextProvisionSorter = 
Optional.of(instance));
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java
index cae2c41632..c123d818b1 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java
@@ -95,12 +95,13 @@ abstract class AbstractPullExecutor<T extends 
ProvisioningTask<T>>
         return 
ctx.getBeanFactory().createBean(DefaultGroupPullResultHandler.class);
     }
 
-    protected List<InboundActions> getInboundActions(final List<? extends 
Implementation> impls) {
+    protected List<InboundActions> getInboundActions(final String domain, 
final List<? extends Implementation> impls) {
         List<InboundActions> result = new ArrayList<>();
 
         impls.forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        domain,
                         impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
@@ -120,7 +121,7 @@ abstract class AbstractPullExecutor<T extends 
ProvisioningTask<T>>
 
         super.init(taskType, taskKey, context);
 
-        provisionSorter = getProvisionSorter(task);
+        provisionSorter = getProvisionSorter(context.getDomain(), task);
 
         latestSyncTokens.clear();
     }
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
index a5f6930f25..41943f3f42 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java
@@ -60,6 +60,7 @@ import 
org.apache.syncope.core.provisioning.api.rules.InboundCorrelationRule;
 import org.apache.syncope.core.provisioning.api.rules.InboundMatch;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -234,8 +235,8 @@ public class InboundMatcher {
             final boolean ignoreCaseMatch) {
 
         String finalConnObjectKeyValue = connObjectKeyValue;
-        for (ItemTransformer transformer
-                : MappingUtils.getItemTransformers(connObjectKeyItem, 
getTransformers(connObjectKeyItem))) {
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(
+                AuthContextUtils.getDomain(), connObjectKeyItem, 
getTransformers(connObjectKeyItem))) {
 
             List<Object> output = transformer.beforePull(
                     connObjectKeyItem,
@@ -365,7 +366,9 @@ public class InboundMatcher {
         if (correlationRule.isPresent()) {
             Implementation impl = correlationRule.get().getImplementation();
             try {
-                rule = ImplementationManager.buildInboundCorrelationRule(impl,
+                rule = ImplementationManager.buildInboundCorrelationRule(
+                        AuthContextUtils.getDomain(),
+                        impl,
                         () -> 
perContextInboundCorrelationRules.get(impl.getKey()),
                         instance -> 
perContextInboundCorrelationRules.put(impl.getKey(), instance));
             } catch (Exception e) {
@@ -452,8 +455,8 @@ public class InboundMatcher {
             return List.of();
         }
 
-        for (ItemTransformer transformer
-                : MappingUtils.getItemTransformers(connObjectKeyItem, 
getTransformers(connObjectKeyItem))) {
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(
+                AuthContextUtils.getDomain(), connObjectKeyItem, 
getTransformers(connObjectKeyItem))) {
 
             List<Object> output = transformer.beforePull(
                     connObjectKeyItem,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java
index 4726995046..0e05150ac5 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java
@@ -105,7 +105,7 @@ public class LiveSyncJobDelegate
                 orElseThrow(() -> new JobExecutionException(
                 "No " + LiveSyncDeltaMapper.class.getSimpleName() + " 
provided, aborting"));
         try {
-            mapper = ImplementationManager.build(impl);
+            mapper = ImplementationManager.build(context.getDomain(), impl);
         } catch (Exception e) {
             throw new JobExecutionException(
                     "Could not build " + 
IdMImplementationType.LIVE_SYNC_DELTA_MAPPER + " " + impl.getKey(), e);
@@ -140,7 +140,7 @@ public class LiveSyncJobDelegate
                 Optional.ofNullable(task.getResource().getInboundPolicy()).
                         map(InboundPolicy::getConflictResolutionAction).
                         orElse(ConflictResolutionAction.IGNORE),
-                getInboundActions(task.getActions()),
+                getInboundActions(context.getDomain(), task.getActions()),
                 executor,
                 context.isDryRun()) {
 
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
index ebd0157255..5fe2d98e3c 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
@@ -43,6 +43,7 @@ import 
org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
 import org.apache.syncope.core.provisioning.api.rules.PushCorrelationRule;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ObjectClass;
@@ -87,6 +88,7 @@ public class OutboundMatcher {
             Implementation impl = correlationRule.get().getImplementation();
             try {
                 rule = ImplementationManager.buildPushCorrelationRule(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> 
perContextPushCorrelationRules.get(impl.getKey()),
                         instance -> 
perContextPushCorrelationRules.put(impl.getKey(), instance));
@@ -157,6 +159,7 @@ public class OutboundMatcher {
         resource.getPropagationActions().forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
index 32ed2fb6bd..f0ab389bbe 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -53,8 +53,11 @@ public class PullJobDelegate
 
     protected Optional<ReconFilterBuilder> perContextReconFilterBuilder = 
Optional.empty();
 
-    protected ReconFilterBuilder getReconFilterBuilder(final PullTask task) 
throws ClassNotFoundException {
+    protected ReconFilterBuilder getReconFilterBuilder(final String domain, 
final PullTask task)
+            throws ClassNotFoundException {
+
         return ImplementationManager.build(
+                domain,
                 task.getReconFilterBuilder(),
                 () -> perContextReconFilterBuilder.orElse(null),
                 instance -> perContextReconFilterBuilder = 
Optional.of(instance));
@@ -75,7 +78,7 @@ public class PullJobDelegate
                 Optional.ofNullable(task.getResource().getInboundPolicy()).
                         map(InboundPolicy::getConflictResolutionAction).
                         orElse(ConflictResolutionAction.IGNORE),
-                getInboundActions(task.getActions()),
+                getInboundActions(context.getDomain(), task.getActions()),
                 executor,
                 context.isDryRun());
 
@@ -139,7 +142,7 @@ public class PullJobDelegate
                     case FILTERED_RECONCILIATION:
                         connector.filteredReconciliation(
                                 new ObjectClass(orgUnit.getObjectClass()),
-                                getReconFilterBuilder(task),
+                                getReconFilterBuilder(context.getDomain(), 
task),
                                 dispatcher,
                                 options);
                         break;
@@ -214,7 +217,7 @@ public class PullJobDelegate
 
                     case FILTERED_RECONCILIATION:
                         connector.filteredReconciliation(new 
ObjectClass(provision.getObjectClass()),
-                                getReconFilterBuilder(task),
+                                getReconFilterBuilder(context.getDomain(), 
task),
                                 dispatcher,
                                 options);
                         break;
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
index aa092cdccf..fe0c2c266d 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
@@ -138,12 +138,13 @@ public class PushJobDelegate
         return 
ctx.getBeanFactory().createBean(DefaultGroupPushResultHandler.class);
     }
 
-    protected List<PushActions> getPushActions(final List<? extends 
Implementation> impls) {
+    protected List<PushActions> getPushActions(final String domain, final 
List<? extends Implementation> impls) {
         List<PushActions> result = new ArrayList<>();
 
         impls.forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        domain,
                         impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
@@ -170,7 +171,7 @@ public class PushJobDelegate
                 Optional.ofNullable(task.getResource().getPushPolicy()).
                         map(PushPolicy::getConflictResolutionAction).
                         orElse(ConflictResolutionAction.IGNORE),
-                getPushActions(task.getActions()),
+                getPushActions(context.getDomain(), task.getActions()),
                 executor,
                 context.isDryRun());
     }
@@ -226,7 +227,7 @@ public class PushJobDelegate
         }
 
         // ...then provisions for any types
-        ProvisionSorter provisionSorter = getProvisionSorter(task);
+        ProvisionSorter provisionSorter = 
getProvisionSorter(context.getDomain(), task);
 
         for (Provision provision : task.getResource().getProvisions().stream().
                 filter(provision -> provision.getMapping() != 
null).sorted(provisionSorter).
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
index ac89668562..7b4f97501f 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
@@ -48,6 +48,7 @@ import 
org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder;
 import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
 import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePullExecutor;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -113,7 +114,7 @@ public class SinglePullJobDelegate extends PullJobDelegate 
implements SyncopeSin
                     taskType,
                     task,
                     ConflictResolutionAction.FIRSTMATCH,
-                    getInboundActions(pullTaskTO.getActions().stream().
+                    getInboundActions(AuthContextUtils.getDomain(), 
pullTaskTO.getActions().stream().
                             
map(implementationDAO::findById).flatMap(Optional::stream).
                             toList()),
                     executor,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
index deaf21e1d9..f0354093ca 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
@@ -39,6 +39,7 @@ import 
org.apache.syncope.core.provisioning.api.pushpull.PushActions;
 import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
 import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePushExecutor;
 import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -73,7 +74,7 @@ public class SinglePushJobDelegate extends PushJobDelegate 
implements SyncopeSin
                 taskType,
                 task,
                 ConflictResolutionAction.FIRSTMATCH,
-                getPushActions(pushTaskTO.getActions().stream().
+                getPushActions(AuthContextUtils.getDomain(), 
pushTaskTO.getActions().stream().
                         
map(implementationDAO::findById).flatMap(Optional::stream).
                         toList()),
                 executor,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
index de35611c03..ad42939663 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java
@@ -51,6 +51,7 @@ import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandle
 import 
org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPullExecutor;
 import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -185,7 +186,7 @@ public class StreamPullJobDelegate extends PullJobDelegate 
implements SyncopeStr
                     taskType,
                     task,
                     conflictResolutionAction,
-                    getInboundActions(pullTaskTO.getActions().stream().
+                    getInboundActions(AuthContextUtils.getDomain(), 
pullTaskTO.getActions().stream().
                             
map(implementationDAO::findById).flatMap(Optional::stream).
                             toList()),
                     executor,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
index 39accfb1da..a8ee30a3ce 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java
@@ -44,6 +44,7 @@ import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandle
 import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
 import 
org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPushExecutor;
 import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -140,7 +141,7 @@ public class StreamPushJobDelegate extends PushJobDelegate 
implements SyncopeStr
                     taskType,
                     task,
                     ConflictResolutionAction.FIRSTMATCH,
-                    getPushActions(pushTaskTO.getActions().stream().
+                    getPushActions(AuthContextUtils.getDomain(), 
pushTaskTO.getActions().stream().
                             
map(implementationDAO::findById).flatMap(Optional::stream).
                             toList()),
                     executor,
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index 9eb69b097a..fd2dcfd67e 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -68,6 +68,7 @@ public final class MappingUtils {
     }
 
     public static List<ItemTransformer> getItemTransformers(
+            final String domain,
             final Item item,
             final List<Implementation> transformers) {
 
@@ -89,6 +90,7 @@ public final class MappingUtils {
         transformers.forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        domain,
                         impl,
                         () -> PER_CONTEXT_ITEM_TRANSFORMERS.get(impl.getKey()),
                         instance -> 
PER_CONTEXT_ITEM_TRANSFORMERS.put(impl.getKey(), instance)));
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/implementation/ImplementationManager.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/implementation/ImplementationManager.java
index 7ccdec209d..99a89b3490 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/implementation/ImplementationManager.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/implementation/ImplementationManager.java
@@ -61,7 +61,7 @@ public final class ImplementationManager {
 
     private static final GroovyClassLoader GROOVY_CLASSLOADER;
 
-    private static final Map<String, Class<?>> CLASS_CACHE = 
Collections.synchronizedMap(new HashMap<>());
+    private static final Map<Pair<String, String>, Class<?>> CLASS_CACHE = 
Collections.synchronizedMap(new HashMap<>());
 
     static {
         CompilerConfiguration cc = new CompilerConfiguration();
@@ -73,6 +73,7 @@ public final class ImplementationManager {
 
     @SuppressWarnings("unchecked")
     public static Optional<ReportJobDelegate> buildReportJobDelegate(
+            final String domain,
             final Implementation impl,
             final Supplier<ReportJobDelegate> cacheGetter,
             final Consumer<ReportJobDelegate> cachePutter)
@@ -80,7 +81,7 @@ public final class ImplementationManager {
 
         switch (impl.getEngine()) {
             case GROOVY:
-                return Optional.of(build(impl, cacheGetter, cachePutter));
+                return Optional.of(build(domain, impl, cacheGetter, 
cachePutter));
 
             case JAVA:
             default:
@@ -101,6 +102,7 @@ public final class ImplementationManager {
 
     @SuppressWarnings("unchecked")
     public static Optional<AccountRule> buildAccountRule(
+            final String domain,
             final Implementation impl,
             final Supplier<AccountRule> cacheGetter,
             final Consumer<AccountRule> cachePutter)
@@ -108,7 +110,7 @@ public final class ImplementationManager {
 
         switch (impl.getEngine()) {
             case GROOVY:
-                return Optional.of(build(impl, cacheGetter, cachePutter));
+                return Optional.of(build(domain, impl, cacheGetter, 
cachePutter));
 
             case JAVA:
             default:
@@ -128,6 +130,7 @@ public final class ImplementationManager {
 
     @SuppressWarnings("unchecked")
     public static Optional<PasswordRule> buildPasswordRule(
+            final String domain,
             final Implementation impl,
             final Supplier<PasswordRule> cacheGetter,
             final Consumer<PasswordRule> cachePutter)
@@ -135,7 +138,7 @@ public final class ImplementationManager {
 
         switch (impl.getEngine()) {
             case GROOVY:
-                return Optional.of(build(impl, cacheGetter, cachePutter));
+                return Optional.of(build(domain, impl, cacheGetter, 
cachePutter));
 
             case JAVA:
             default:
@@ -155,6 +158,7 @@ public final class ImplementationManager {
 
     @SuppressWarnings("unchecked")
     public static Optional<InboundCorrelationRule> buildInboundCorrelationRule(
+            final String domain,
             final Implementation impl,
             final Supplier<InboundCorrelationRule> cacheGetter,
             final Consumer<InboundCorrelationRule> cachePutter)
@@ -162,7 +166,7 @@ public final class ImplementationManager {
 
         switch (impl.getEngine()) {
             case GROOVY:
-                return Optional.of(build(impl, cacheGetter, cachePutter));
+                return Optional.of(build(domain, impl, cacheGetter, 
cachePutter));
 
             case JAVA:
             default:
@@ -183,6 +187,7 @@ public final class ImplementationManager {
 
     @SuppressWarnings("unchecked")
     public static Optional<PushCorrelationRule> buildPushCorrelationRule(
+            final String domain,
             final Implementation impl,
             final Supplier<PushCorrelationRule> cacheGetter,
             final Consumer<PushCorrelationRule> cachePutter)
@@ -190,7 +195,7 @@ public final class ImplementationManager {
 
         switch (impl.getEngine()) {
             case GROOVY:
-                return Optional.of(build(impl, cacheGetter, cachePutter));
+                return Optional.of(build(domain, impl, cacheGetter, 
cachePutter));
 
             case JAVA:
             default:
@@ -229,12 +234,12 @@ public final class ImplementationManager {
         return null;
     }
 
-    public static CommandArgs emptyArgs(final Implementation impl) throws 
Exception {
+    public static CommandArgs emptyArgs(final String domain, final 
Implementation impl) throws Exception {
         if (!IdRepoImplementationType.COMMAND.equals(impl.getType())) {
             throw new IllegalArgumentException("This method can be only called 
on implementations");
         }
 
-        Class<Object> commandClass = getClass(impl).getLeft();
+        Class<Object> commandClass = getClass(domain, impl).getLeft();
 
         Class<? extends CommandArgs> commandArgsClass = 
findCommandArgsClass(commandClass);
         if (commandArgsClass != null
@@ -249,9 +254,12 @@ public final class ImplementationManager {
     }
 
     @SuppressWarnings("unchecked")
-    public static <T> Pair<Class<T>, Boolean> getClass(final Implementation 
impl) throws ClassNotFoundException {
-        if (CLASS_CACHE.containsKey(impl.getKey())) {
-            return Pair.of((Class<T>) CLASS_CACHE.get(impl.getKey()), true);
+    public static <T> Pair<Class<T>, Boolean> getClass(final String domain, 
final Implementation impl)
+            throws ClassNotFoundException {
+
+        Pair<String, String> cacheKey = Pair.of(domain, impl.getKey());
+        if (CLASS_CACHE.containsKey(cacheKey)) {
+            return Pair.of((Class<T>) CLASS_CACHE.get(cacheKey), true);
         }
 
         Class<?> clazz;
@@ -265,7 +273,7 @@ public final class ImplementationManager {
                 clazz = Class.forName(impl.getBody());
         }
 
-        CLASS_CACHE.put(impl.getKey(), clazz);
+        CLASS_CACHE.put(cacheKey, clazz);
         return Pair.of((Class<T>) clazz, false);
     }
 
@@ -289,8 +297,8 @@ public final class ImplementationManager {
     }
 
     @SuppressWarnings("unchecked")
-    public static <T> T build(final Implementation impl) throws 
ClassNotFoundException {
-        return createBean((Class<T>) getClass(impl).getLeft(), 
impl.getEngine());
+    public static <T> T build(final String domain, final Implementation impl) 
throws ClassNotFoundException {
+        return createBean((Class<T>) getClass(domain, impl).getLeft(), 
impl.getEngine());
     }
 
     @SuppressWarnings("unchecked")
@@ -319,16 +327,20 @@ public final class ImplementationManager {
         return instance;
     }
 
-    public static <T> T build(final Implementation impl, final Supplier<T> 
cacheGetter, final Consumer<T> cachePutter)
+    public static <T> T build(
+            final String domain,
+            final Implementation impl,
+            final Supplier<T> cacheGetter,
+            final Consumer<T> cachePutter)
             throws ClassNotFoundException {
 
-        Pair<Class<T>, Boolean> clazz = getClass(impl);
+        Pair<Class<T>, Boolean> clazz = getClass(domain, impl);
 
         return build(clazz.getLeft(), clazz.getRight(), impl.getEngine(), 
cacheGetter, cachePutter);
     }
 
-    public static Class<?> purge(final String implementation) {
-        return CLASS_CACHE.remove(implementation);
+    public static Class<?> purge(final String domain, final String 
implementation) {
+        return CLASS_CACHE.remove(Pair.of(domain, implementation));
     }
 
     private ImplementationManager() {
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultRuleProvider.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultRuleProvider.java
index aa459bb626..8190f7cba5 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultRuleProvider.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultRuleProvider.java
@@ -34,6 +34,7 @@ import 
org.apache.syncope.core.provisioning.api.rules.AccountRule;
 import org.apache.syncope.core.provisioning.api.rules.PasswordRule;
 import org.apache.syncope.core.provisioning.api.rules.RuleProvider;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.transaction.annotation.Transactional;
@@ -82,6 +83,7 @@ public class DefaultRuleProvider implements RuleProvider {
         for (Implementation impl : policy.getRules()) {
             try {
                 ImplementationManager.buildAccountRule(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextAccountRules.get(impl.getKey()),
                         instance -> perContextAccountRules.put(impl.getKey(), 
instance)).
@@ -124,6 +126,7 @@ public class DefaultRuleProvider implements RuleProvider {
         for (Implementation impl : policy.getRules()) {
             try {
                 ImplementationManager.buildPasswordRule(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextPasswordRules.get(impl.getKey()),
                         instance -> perContextPasswordRules.put(impl.getKey(), 
instance)).
diff --git 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
index 8ee5ad2f38..98e82b737a 100644
--- 
a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
+++ 
b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
@@ -77,6 +77,7 @@ public class DefaultPasswordGenerator implements 
PasswordGenerator {
         for (Implementation impl : policy.getRules()) {
             try {
                 ImplementationManager.buildPasswordRule(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextPasswordRules.get(impl.getKey()),
                         instance -> perContextPasswordRules.put(impl.getKey(), 
instance)).
diff --git 
a/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/GroovySandboxTest.java
 
b/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/GroovySandboxTest.java
index fe2e0641bf..b301f9f2a7 100644
--- 
a/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/GroovySandboxTest.java
+++ 
b/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/GroovySandboxTest.java
@@ -30,6 +30,7 @@ import java.util.Map;
 import java.util.Objects;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.provisioning.api.macro.MacroActions;
@@ -63,7 +64,7 @@ class GroovySandboxTest {
         when(impl.getBody()).thenReturn(IOUtils.toString(
                 
Objects.requireNonNull(getClass().getResourceAsStream(resource))));
 
-        return ImplementationManager.build(impl);
+        return ImplementationManager.build(SyncopeConstants.MASTER_DOMAIN, 
impl);
     }
 
     @EnabledOnOs(OS.LINUX)
diff --git 
a/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/PasswordRuleTest.java
 
b/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/PasswordRuleTest.java
index d7edb9723d..b0cd17778f 100644
--- 
a/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/PasswordRuleTest.java
+++ 
b/core/spring/src/test/java/org/apache/syncope/core/spring/implementation/PasswordRuleTest.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.SpringTestConfiguration;
@@ -68,6 +69,7 @@ public class PasswordRuleTest {
                         }
                         try {
                             ImplementationManager.buildPasswordRule(
+                                    SyncopeConstants.MASTER_DOMAIN,
                                     impl,
                                     () -> null,
                                     instance -> {
diff --git 
a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
 
b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
index 33796a0a6a..23b7a9244e 100644
--- 
a/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
+++ 
b/ext/oidcc4ui/logic/src/main/java/org/apache/syncope/core/logic/oidc/OIDCUserManager.java
@@ -52,6 +52,7 @@ import 
org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
 import org.apache.syncope.core.provisioning.java.pushpull.InboundMatcher;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.transaction.annotation.Propagation;
@@ -115,6 +116,7 @@ public class OIDCUserManager {
         op.getActions().forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
@@ -141,7 +143,9 @@ public class OIDCUserManager {
                 values.addAll(oidcAttr.get().getValues());
 
                 List<Object> transformed = new ArrayList<>(values);
-                for (ItemTransformer transformer : 
MappingUtils.getItemTransformers(item, getTransformers(item))) {
+                for (ItemTransformer transformer
+                        : 
MappingUtils.getItemTransformers(AuthContextUtils.getDomain(), item, 
getTransformers(item))) {
+
                     transformed = transformer.beforePull(null, userTO, 
transformed);
                 }
                 values.clear();
diff --git 
a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
 
b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
index 69d025743e..d2c3244502 100644
--- 
a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
+++ 
b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/SAML2SP4UILogic.java
@@ -256,6 +256,7 @@ public class SAML2SP4UILogic extends 
AbstractSAML2SP4UILogic {
         if (impl != null) {
             try {
                 return Optional.of(ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextRACP.get(impl.getKey()),
                         instance -> perContextRACP.put(impl.getKey(), 
instance)));
diff --git 
a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2SP4UIUserManager.java
 
b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2SP4UIUserManager.java
index 8aa5d1a492..810a3d7fa3 100644
--- 
a/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2SP4UIUserManager.java
+++ 
b/ext/saml2sp4ui/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2SP4UIUserManager.java
@@ -53,6 +53,7 @@ import 
org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
 import org.apache.syncope.core.provisioning.java.pushpull.InboundMatcher;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.transaction.annotation.Propagation;
@@ -126,6 +127,7 @@ public class SAML2SP4UIUserManager {
         idp.getActions().forEach(impl -> {
             try {
                 result.add(ImplementationManager.build(
+                        AuthContextUtils.getDomain(),
                         impl,
                         () -> perContextActions.get(impl.getKey()),
                         instance -> perContextActions.put(impl.getKey(), 
instance)));
@@ -158,7 +160,9 @@ public class SAML2SP4UIUserManager {
                 values = samlAttr.get().getValues();
 
                 List<Object> transformed = new ArrayList<>(values);
-                for (ItemTransformer transformer : 
MappingUtils.getItemTransformers(item, getTransformers(item))) {
+                for (ItemTransformer transformer
+                        : 
MappingUtils.getItemTransformers(AuthContextUtils.getDomain(), item, 
getTransformers(item))) {
+
                     transformed = transformer.beforePull(null, userTO, 
transformed);
                 }
                 values.clear();

Reply via email to