You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/07/10 16:36:01 UTC

[4/4] syncope git commit: [SYNCOPE-1143] Now connector instances require an admin realm, which is used to enforce access control on it for administrative purposes

[SYNCOPE-1143] Now connector instances require an admin realm, which is used to enforce access control on it for administrative purposes


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/9779e13e
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/9779e13e
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/9779e13e

Branch: refs/heads/master
Commit: 9779e13e0d55efa445c6b046c51781d55d91991d
Parents: f1eaaa2
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jul 10 18:35:33 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jul 10 18:35:46 2017 +0200

----------------------------------------------------------------------
 .../client/console/SyncopeConsoleSession.java   | 28 ++++-----
 .../client/console/panels/RealmChoicePanel.java | 11 ++--
 .../client/console/topology/Topology.java       | 49 +++++++++------
 .../console/wizards/any/AnyWizardBuilder.java   |  7 +--
 .../client/console/wizards/any/Details.java     |  3 +-
 .../console/wizards/any/UserWizardBuilder.java  |  1 -
 .../resources/ConnectorDetailsPanel.java        | 49 +++++++++++++++
 .../resources/ConnectorDetailsPanel.html        |  4 ++
 .../resources/ConnectorDetailsPanel.properties  |  1 +
 .../ConnectorDetailsPanel_it.properties         |  1 +
 .../ConnectorDetailsPanel_pt_BR.properties      |  1 +
 .../ConnectorDetailsPanel_ru.properties         |  1 +
 .../syncope/common/lib/to/ConnInstanceTO.java   | 10 +++
 .../syncope/core/logic/AbstractAnyLogic.java    | 53 ++--------------
 .../syncope/core/logic/AnyObjectLogic.java      | 23 +++----
 .../syncope/core/logic/ConnectorLogic.java      | 53 +++++++++++++++-
 .../apache/syncope/core/logic/GroupLogic.java   | 30 ++++-----
 .../syncope/core/logic/ResourceLogic.java       | 66 +++++++++++++++++---
 .../apache/syncope/core/logic/UserLogic.java    | 38 +++++------
 .../persistence/api/dao/ConnInstanceDAO.java    |  2 +
 .../api/dao/ExternalResourceDAO.java            |  6 +-
 .../persistence/api/entity/ConnInstance.java    |  4 ++
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |  2 +-
 .../persistence/jpa/dao/JPAConnInstanceDAO.java | 54 +++++++++++++++-
 .../jpa/dao/JPAExternalResourceDAO.java         | 49 ++++++++++-----
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |  2 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  2 +-
 .../persistence/jpa/entity/AbstractAny.java     |  2 +-
 .../persistence/jpa/entity/JPAConnInstance.java | 16 +++++
 .../persistence/jpa/inner/ConnInstanceTest.java | 55 +++++++++++++---
 .../persistence/jpa/inner/ResourceTest.java     | 15 ++---
 .../test/resources/domains/MasterContent.xml    | 26 +++++++-
 .../src/test/resources/domains/TwoContent.xml   |  1 +
 .../core/provisioning/api/utils/RealmUtils.java | 47 ++++++++++++++
 .../provisioning/java/ConnectorManager.java     |  1 +
 .../java/data/ConnInstanceDataBinderImpl.java   | 44 ++++++++-----
 .../DelegatedAdministrationException.java       |  2 +-
 .../syncope/fit/core/ConnectorITCase.java       | 54 ++++++++++++++++
 .../syncope/fit/core/MigrationITCase.java       |  2 +
 .../apache/syncope/fit/core/ResourceITCase.java | 31 +++++++++
 40 files changed, 632 insertions(+), 214 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index af8295a..ab84d10 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -19,9 +19,10 @@
 package org.apache.syncope.client.console;
 
 import java.text.DateFormat;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -29,9 +30,9 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.MediaType;
-import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.list.SetUniqueList;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.commons.lang3.tuple.Pair;
@@ -217,25 +218,18 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
         return selfTO;
     }
 
-    public Set<String> getAvailableRealms(final String... entitlements) {
-        final Set<String> availableRealms = new HashSet<>();
-        if (entitlements != null && entitlements.length > 0) {
-            for (String entitlement : entitlements) {
-                final Set<String> realms = auth.get(entitlement);
-                if (CollectionUtils.isNotEmpty(realms)) {
-                    availableRealms.addAll(realms);
-                }
-            }
-        } else {
-            for (Map.Entry<String, Set<String>> entitlement : auth.entrySet()) {
-                availableRealms.addAll(entitlement.getValue());
-            }
+    public List<String> getAuthRealms() {
+        List<String> sortable = new ArrayList<>();
+        List<String> available = SetUniqueList.setUniqueList(sortable);
+        for (Map.Entry<String, Set<String>> entitlement : auth.entrySet()) {
+            available.addAll(entitlement.getValue());
         }
-        return availableRealms;
+        Collections.sort(sortable);
+        return sortable;
     }
 
     public boolean owns(final String entitlements) {
-        return owns(entitlements, "/");
+        return owns(entitlements, SyncopeConstants.ROOT_REALM);
     }
 
     public boolean owns(final String entitlements, final String realm) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
index bfbb460..d569b14 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -27,12 +27,12 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.image.GlyphIconType;
 import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
@@ -72,7 +72,7 @@ public class RealmChoicePanel extends Panel {
 
     private final Model<RealmTO> model;
 
-    private final Set<String> availableRealms;
+    private final Collection<String> availableRealms;
 
     private final Map<String, Pair<RealmTO, List<RealmTO>>> tree;
 
@@ -146,13 +146,13 @@ public class RealmChoicePanel extends Panel {
         container.setOutputMarkupId(true);
         add(container);
 
-        availableRealms = SyncopeConsoleSession.get().getAvailableRealms();
+        availableRealms = SyncopeConsoleSession.get().getAuthRealms();
 
         reloadRealmTree();
     }
 
     public final void reloadRealmTree() {
-        final Label realmLabel = new Label("realmLabel", new Model<String>());
+        final Label realmLabel = new Label("realmLabel", new Model<>());
         realmLabel.setOutputMarkupId(true);
 
         container.addOrReplace(realmLabel);
@@ -186,7 +186,6 @@ public class RealmChoicePanel extends Panel {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target) {
-
                     }
 
                     @Override
@@ -288,7 +287,7 @@ public class RealmChoicePanel extends Panel {
 
                                     @Override
                                     public boolean evaluate(final String availableRealm) {
-                                        return "/".equals(availableRealm)
+                                        return SyncopeConstants.ROOT_REALM.equals(availableRealm)
                                                 || realmTO.getKey().equals(availableRealm);
                                     }
                                 });

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index d2ba682..606a32d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -22,10 +22,13 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
@@ -39,6 +42,7 @@ import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -92,8 +96,8 @@ public class Topology extends BasePage {
         }
     };
 
-    private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel
-            = new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
+    private final LoadableDetachableModel<Map<String, List<ConnInstanceTO>>> connModel =
+            new LoadableDetachableModel<Map<String, List<ConnInstanceTO>>>() {
 
         private static final long serialVersionUID = 5275935387613157432L;
 
@@ -116,8 +120,8 @@ public class Topology extends BasePage {
         }
     };
 
-    private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel
-            = new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
+    private final LoadableDetachableModel<Pair<List<URI>, List<URI>>> csModel =
+            new LoadableDetachableModel<Pair<List<URI>, List<URI>>>() {
 
         private static final long serialVersionUID = 5275935387613157433L;
 
@@ -177,7 +181,7 @@ public class Topology extends BasePage {
             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
                 target.appendJavaScript("zoomIn($('#drawing')[0]);");
             }
-        }, ActionLink.ActionType.ZOOM_IN, StandardEntitlement.RESOURCE_LIST).disableIndicator().hideLabel();
+        }, ActionLink.ActionType.ZOOM_IN, StandardEntitlement.CONNECTOR_LIST).disableIndicator().hideLabel();
         zoomActionPanel.add(new ActionLink<Serializable>() {
 
             private static final long serialVersionUID = -3722207913631435501L;
@@ -186,7 +190,7 @@ public class Topology extends BasePage {
             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
                 target.appendJavaScript("zoomOut($('#drawing')[0]);");
             }
-        }, ActionLink.ActionType.ZOOM_OUT, StandardEntitlement.RESOURCE_LIST).disableIndicator().hideLabel();
+        }, ActionLink.ActionType.ZOOM_OUT, StandardEntitlement.CONNECTOR_LIST).disableIndicator().hideLabel();
 
         body.add(zoomActionPanel);
         // -----------------------------------------
@@ -366,24 +370,31 @@ public class Topology extends BasePage {
         // -----------------------------------------
         // Add Resources
         // -----------------------------------------
+        final Collection<String> administrableConns = new HashSet<>();
+        for (List<ConnInstanceTO> connInstances : connModel.getObject().values()) {
+            administrableConns.addAll(CollectionUtils.collect(connInstances, EntityTOUtils.keyTransformer()));
+        }
+
         final List<String> connToBeProcessed = new ArrayList<>();
-        for (ResourceTO resourceTO : resModel.getObject()) {
-            final TopologyNode topologynode = new TopologyNode(
-                    resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
+        for (final ResourceTO resourceTO : resModel.getObject()) {
+            if (administrableConns.contains(resourceTO.getConnector())) {
+                final TopologyNode topologynode = new TopologyNode(
+                        resourceTO.getKey(), resourceTO.getKey(), TopologyNode.Kind.RESOURCE);
 
-            final Map<Serializable, TopologyNode> remoteConnections;
+                final Map<Serializable, TopologyNode> remoteConnections;
 
-            if (connections.containsKey(resourceTO.getConnector())) {
-                remoteConnections = connections.get(resourceTO.getConnector());
-            } else {
-                remoteConnections = new HashMap<>();
-                connections.put(resourceTO.getConnector(), remoteConnections);
-            }
+                if (connections.containsKey(resourceTO.getConnector())) {
+                    remoteConnections = connections.get(resourceTO.getConnector());
+                } else {
+                    remoteConnections = new HashMap<>();
+                    connections.put(resourceTO.getConnector(), remoteConnections);
+                }
 
-            remoteConnections.put(topologynode.getKey(), topologynode);
+                remoteConnections.put(topologynode.getKey(), topologynode);
 
-            if (!connToBeProcessed.contains(resourceTO.getConnector())) {
-                connToBeProcessed.add(resourceTO.getConnector());
+                if (!connToBeProcessed.contains(resourceTO.getConnector())) {
+                    connToBeProcessed.add(resourceTO.getConnector());
+                }
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index 9b3bce6..37377ef 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -152,15 +152,14 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde
     }
 
     protected Details<A> addOptionalDetailsPanel(final AnyWrapper<A> modelObject) {
-
-        if (modelObject.getInnerObject().getKey() != null) {
+        if (modelObject.getInnerObject().getKey() == null) {
+            return null;
+        } else {
             return new Details<>(
                     modelObject,
                     mode == AjaxWizard.Mode.TEMPLATE,
                     true,
                     pageRef);
-        } else {
-            return null;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
index e5a92d2..a7dd79a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Details.java
@@ -73,8 +73,7 @@ public class Details<T extends AnyTO> extends WizardStep {
                     "destinationRealm", "destinationRealm", new PropertyModel<String>(inner, "realm"), false);
 
             ((AjaxDropDownChoicePanel<String>) realm).setChoices(CollectionUtils.collect(
-                    realms,
-                    new Transformer<RealmTO, String>() {
+                    realms, new Transformer<RealmTO, String>() {
 
                 @Override
                 public String transform(final RealmTO input) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index f56e24d..6cf6023 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -104,7 +104,6 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
 
     @Override
     protected Details<UserTO> addOptionalDetailsPanel(final AnyWrapper<UserTO> modelObject) {
-
         return new UserDetails(
                 UserWrapper.class.cast(modelObject),
                 mode == AjaxWizard.Mode.TEMPLATE,

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
index 89c692f..43d4d85 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
@@ -19,12 +19,16 @@
 package org.apache.syncope.client.console.wizards.resources;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.RealmRestClient;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
@@ -32,19 +36,64 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPa
 import org.apache.syncope.common.lib.to.ConnBundleTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.PropertyModel;
 
 public class ConnectorDetailsPanel extends WizardStep {
 
     private static final long serialVersionUID = -2435937897614232137L;
 
+    private final LoadableDetachableModel<List<String>> realms;
+
     public ConnectorDetailsPanel(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
         super();
         setOutputMarkupId(true);
 
+        final List<String> authRealms = SyncopeConsoleSession.get().getAuthRealms();
+        realms = new LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                List<RealmTO> allRealms = new RealmRestClient().list();
+                CollectionUtils.filter(allRealms, new Predicate<RealmTO>() {
+
+                    @Override
+                    public boolean evaluate(final RealmTO realm) {
+                        return IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+                            @Override
+                            public boolean evaluate(final String fullpath) {
+                                return realm.getFullPath().startsWith(fullpath);
+                            }
+                        });
+                    }
+                });
+
+                List<String> result = CollectionUtils.collect(allRealms, new Transformer<RealmTO, String>() {
+
+                    @Override
+                    public String transform(final RealmTO realm) {
+                        return realm.getFullPath();
+                    }
+                }, new ArrayList<String>());
+                Collections.sort(result);
+                return result;
+            }
+        };
+
+        AjaxDropDownChoicePanel<String> realm = new AjaxDropDownChoicePanel<>(
+                "adminRealm", "adminRealm", new PropertyModel<String>(connInstanceTO, "adminRealm"), false);
+        realm.setChoices(realms);
+        realm.setOutputMarkupId(true);
+        realm.addRequiredLabel();
+        add(realm);
+
         AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
                 "displayName", "displayName", new PropertyModel<String>(connInstanceTO, "displayName"), false);
         displayName.setOutputMarkupId(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
index 87fc624..01ac512 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.html
@@ -23,6 +23,10 @@ under the License.
   <body>
     <wicket:panel>
       <div class="form-group">
+        <span wicket:id="adminRealm">[adminRealm]</span>
+      </div>
+
+      <div class="form-group">
         <span wicket:id="displayName">[displayName]</span>
       </div>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
index 6c11adc..23711a9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.properties
@@ -24,3 +24,4 @@ poolMinIdle=Min idle objects
 poolMaxIdle=Max idle objects
 poolMaxWait=Max waiting time (msec)
 poolMinEvictableIdleTime=Min eviction time (msec)
+adminRealm=Administration Realm

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
index ed69987..0fd9aa7 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_it.properties
@@ -24,3 +24,4 @@ poolMinIdle=Max oggetti attivi
 poolMaxIdle=Max oggetti inattivi
 poolMaxWait=Tempo max attesa
 poolMinEvictableIdleTime=Tempo min espulsione
+adminRealm=Realm di amministrazione

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
index a2915b1..db06733 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_pt_BR.properties
@@ -24,3 +24,4 @@ poolMinIdle=Min idle objects
 poolMaxIdle=Max idle objects
 poolMaxWait=Max waiting time (msec)
 poolMinEvictableIdleTime=Min eviction time (msec)
+adminRealm=Administration Realm

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
index 0194990..c5d4b3f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel_ru.properties
@@ -25,3 +25,4 @@ poolMinIdle=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0431\u044a\u0435\
 poolMaxIdle=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438
 poolMaxWait=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f (\u043c\u0441)
 poolMinEvictableIdleTime=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f (\u043c\u0441)
+adminRealm=Administration Realm

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
index d7c8be7..9440972 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
@@ -42,6 +42,8 @@ public class ConnInstanceTO extends AbstractBaseBean implements EntityTO {
 
     private String key;
 
+    private String adminRealm;
+
     private String location;
 
     private String connectorName;
@@ -71,6 +73,14 @@ public class ConnInstanceTO extends AbstractBaseBean implements EntityTO {
         this.key = key;
     }
 
+    public String getAdminRealm() {
+        return adminRealm;
+    }
+
+    public void setAdminRealm(final String adminRealm) {
+        this.adminRealm = adminRealm;
+    }
+
     public String getLocation() {
         return location;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index 7c96979..bf83632 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.logic;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -40,7 +39,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
@@ -53,6 +51,7 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 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.LogicActions;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 
@@ -230,50 +229,6 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
         return result;
     }
 
-    private static class StartsWithPredicate implements Predicate<String> {
-
-        private final Collection<String> targets;
-
-        StartsWithPredicate(final Collection<String> targets) {
-            this.targets = targets;
-        }
-
-        @Override
-        public boolean evaluate(final String realm) {
-            return IterableUtils.matchesAny(targets, new Predicate<String>() {
-
-                @Override
-                public boolean evaluate(final String target) {
-                    return realm.startsWith(target);
-                }
-            });
-        }
-
-    }
-
-    protected static class DynRealmsPredicate implements Predicate<String> {
-
-        @Override
-        public boolean evaluate(final String realm) {
-            return !realm.startsWith("/");
-        }
-    }
-
-    protected Set<String> getEffectiveRealms(final Set<String> allowedRealms, final String requestedRealm) {
-        Set<String> allowed = RealmUtils.normalize(allowedRealms);
-        Set<String> requested = new HashSet<>();
-        requested.add(requestedRealm);
-
-        Set<String> effective = new HashSet<>();
-        CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
-        CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
-
-        // includes dynamic realms
-        CollectionUtils.select(allowedRealms, new DynRealmsPredicate(), effective);
-
-        return effective;
-    }
-
     protected boolean securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
         boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
 
@@ -293,15 +248,15 @@ public abstract class AbstractAnyLogic<TO extends AnyTO, P extends AnyPatch> ext
         if (!authorized) {
             throw new DelegatedAdministrationException(
                     realm,
-                    this instanceof UserLogic
+                    (this instanceof UserLogic
                             ? AnyTypeKind.USER
                             : this instanceof GroupLogic
                                     ? AnyTypeKind.GROUP
-                                    : AnyTypeKind.ANY_OBJECT,
+                                    : AnyTypeKind.ANY_OBJECT).name(),
                     key);
         }
 
-        return IterableUtils.matchesAny(effectiveRealms, new DynRealmsPredicate());
+        return IterableUtils.matchesAny(effectiveRealms, new RealmUtils.DynRealmsPredicate());
     }
 
     public abstract Date findLastChange(String key);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 8805221..49d18db 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
 import org.apache.syncope.core.provisioning.api.LogicActions;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -109,7 +110,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             throw new UnsupportedOperationException("Need to specify " + AnyType.class.getSimpleName());
         }
 
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.SEARCH.getFor(searchCond.hasAnyTypeCond())),
                 realm);
 
@@ -125,7 +126,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             throw new UnsupportedOperationException("Need to specify " + AnyType.class.getSimpleName());
         }
 
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.SEARCH.getFor(searchCond.hasAnyTypeCond())),
                 realm);
 
@@ -152,7 +153,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
             throw SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
         }
 
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.CREATE.getFor(before.getLeft().getType())),
                 before.getLeft().getRealm());
         securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -174,7 +175,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
                 before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
                 ? before.getLeft().getRealm().getValue()
                 : anyObjectTO.getRealm();
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 realm);
         boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
@@ -194,7 +195,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
         AnyObjectTO anyObject = binder.getAnyObjectTO(key);
         Pair<AnyObjectTO, List<LogicActions>> before = beforeDelete(anyObject);
 
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.DELETE.getFor(before.getLeft().getType())),
                 before.getLeft().getRealm());
         securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -211,7 +212,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
     public AnyObjectTO unlink(final String key, final Collection<String> resources) {
         // security checks
         AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 anyObjectTO.getRealm());
         securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -233,7 +234,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
     public AnyObjectTO link(final String key, final Collection<String> resources) {
         // security checks
         AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 anyObjectTO.getRealm());
         securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -257,7 +258,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
 
         // security checks
         AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 anyObjectTO.getRealm());
         securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -285,7 +286,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
 
         // security checks
         AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 anyObjectTO.getRealm());
         securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -309,7 +310,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
 
         // security checks
         AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 anyObjectTO.getRealm());
         securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());
@@ -332,7 +333,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectPatch
 
         // security checks
         AnyObjectTO anyObjectTO = binder.getAnyObjectTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(AnyEntitlement.UPDATE.getFor(anyObjectTO.getType())),
                 anyObjectTO.getRealm());
         securityChecks(effectiveRealms, anyObjectTO.getRealm(), anyObjectTO.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index e84dfe5..6532936 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -26,6 +26,8 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.PredicateUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
@@ -44,6 +46,9 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.identityconnectors.common.l10n.CurrentLocale;
 import org.identityconnectors.framework.api.ConfigurationProperties;
 import org.identityconnectors.framework.api.ConnectorInfo;
@@ -75,23 +80,61 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     @Autowired
     private ConnectorFactory connFactory;
 
+    protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+        boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String ownedRealm) {
+                return realm.startsWith(ownedRealm);
+            }
+        });
+        if (!authorized) {
+            throw new DelegatedAdministrationException(realm, ConnInstance.class.getSimpleName(), key);
+        }
+    }
+
     @PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_CREATE + "')")
     public ConnInstanceTO create(final ConnInstanceTO connInstanceTO) {
+        if (connInstanceTO.getAdminRealm() == null) {
+            throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+        }
+
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_CREATE),
+                connInstanceTO.getAdminRealm());
+        securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), null);
+
         return binder.getConnInstanceTO(connInstanceDAO.save(binder.getConnInstance(connInstanceTO)));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_UPDATE + "')")
     public ConnInstanceTO update(final ConnInstanceTO connInstanceTO) {
+        if (connInstanceTO.getAdminRealm() == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
+            sce.getElements().add("Invalid or null realm specified: " + connInstanceTO.getAdminRealm());
+            throw sce;
+        }
+
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_UPDATE),
+                connInstanceTO.getAdminRealm());
+        securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), connInstanceTO.getKey());
+
         return binder.getConnInstanceTO(binder.update(connInstanceTO));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_DELETE + "')")
     public ConnInstanceTO delete(final String key) {
-        ConnInstance connInstance = connInstanceDAO.find(key);
+        ConnInstance connInstance = connInstanceDAO.authFind(key);
         if (connInstance == null) {
             throw new NotFoundException("Connector '" + key + "'");
         }
 
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_DELETE),
+                connInstance.getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, connInstance.getAdminRealm().getFullPath(), connInstance.getKey());
+
         if (!connInstance.getResources().isEmpty()) {
             SyncopeClientException associatedResources = SyncopeClientException.build(
                     ClientExceptionType.AssociatedResources);
@@ -136,7 +179,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     public ConnInstanceTO read(final String key, final String lang) {
         CurrentLocale.set(StringUtils.isBlank(lang) ? Locale.ENGLISH : new Locale(lang));
 
-        ConnInstance connInstance = connInstanceDAO.find(key);
+        ConnInstance connInstance = connInstanceDAO.authFind(key);
         if (connInstance == null) {
             throw new NotFoundException("Connector '" + key + "'");
         }
@@ -183,7 +226,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     public List<ConnIdObjectClassTO> buildObjectClassInfo(
             final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
 
-        ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+        ConnInstance connInstance = connInstanceDAO.authFind(connInstanceTO.getKey());
         if (connInstance == null) {
             throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
         }
@@ -214,6 +257,10 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     @PreAuthorize("hasRole('" + StandardEntitlement.CONNECTOR_READ + "')")
     @Transactional(readOnly = true)
     public void check(final ConnInstanceTO connInstanceTO) {
+        if (connInstanceTO.getAdminRealm() == null) {
+            throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+        }
+
         connFactory.createConnector(binder.getConnInstance(connInstanceTO)).test();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index ca3e080..7e9b88b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -122,10 +122,10 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
             authorized = !CollectionUtils.intersection(groupDAO.findDynRealms(key), effectiveRealms).isEmpty();
         }
         if (!authorized) {
-            throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP, key);
+            throw new DelegatedAdministrationException(realm, AnyTypeKind.GROUP.name(), key);
         }
 
-        return IterableUtils.matchesAny(effectiveRealms, new AbstractAnyLogic.DynRealmsPredicate());
+        return IterableUtils.matchesAny(effectiveRealms, new RealmUtils.DynRealmsPredicate());
     }
 
     @Transactional(readOnly = true)
@@ -177,7 +177,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
     @Transactional(readOnly = true)
     @Override
     public int count(final String realm) {
-        return groupDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm));
+        return groupDAO.count(RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm));
     }
 
     @PreAuthorize("isAuthenticated()")
@@ -188,7 +188,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
             final String realm, final boolean details) {
 
         return CollectionUtils.collect(groupDAO.findAll(
-                getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+                RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
                 page, size, orderBy),
                 new Transformer<Group, GroupTO>() {
 
@@ -205,7 +205,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
     @Override
     public int searchCount(final SearchCond searchCondition, final String realm) {
         return searchDAO.count(
-                getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+                RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
                 searchCondition, AnyTypeKind.GROUP);
     }
 
@@ -216,7 +216,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
             final List<OrderByClause> orderBy, final String realm, final boolean details) {
 
         List<Group> matchingGroups = searchDAO.search(
-                getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realm),
+                RealmUtils.getEffective(SyncopeConstants.FULL_ADMIN_REALMS, realm),
                 searchCondition, page, size, orderBy, AnyTypeKind.GROUP);
         return CollectionUtils.collect(matchingGroups, new Transformer<Group, GroupTO>() {
 
@@ -237,7 +237,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
             throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
 
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_CREATE),
                 before.getLeft().getRealm());
         securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -259,7 +259,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
                 before.getLeft().getRealm() != null && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())
                 ? before.getLeft().getRealm().getValue()
                 : groupTO.getRealm();
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 realm);
         boolean authDynRealms = securityChecks(effectiveRealms, realm, before.getLeft().getKey());
@@ -280,7 +280,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
         GroupTO group = binder.getGroupTO(key);
         Pair<GroupTO, List<LogicActions>> before = beforeDelete(group);
 
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_DELETE),
                 before.getLeft().getRealm());
         securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -312,7 +312,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
     public GroupTO unlink(final String key, final Collection<String> resources) {
         // security checks
         GroupTO group = binder.getGroupTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 group.getRealm());
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -335,7 +335,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
     public GroupTO link(final String key, final Collection<String> resources) {
         // security checks
         GroupTO group = binder.getGroupTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 group.getRealm());
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -360,7 +360,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
 
         // security checks
         GroupTO group = binder.getGroupTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 group.getRealm());
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -389,7 +389,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
 
         // security checks
         GroupTO group = binder.getGroupTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 group.getRealm());
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -414,7 +414,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
 
         // security checks
         GroupTO group = binder.getGroupTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 group.getRealm());
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());
@@ -438,7 +438,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupPatch> {
 
         // security checks
         GroupTO group = binder.getGroupTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.GROUP_UPDATE),
                 group.getRealm());
         securityChecks(effectiveRealms, group.getRealm(), group.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 5269c1e..1cde745 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -25,7 +25,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.ArrayUtils;
@@ -62,7 +64,10 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -113,6 +118,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     @Autowired
     private ConnectorFactory connFactory;
 
+    protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+        boolean authorized = IterableUtils.matchesAny(effectiveRealms, new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String ownedRealm) {
+                return realm.startsWith(ownedRealm);
+            }
+        });
+        if (!authorized) {
+            throw new DelegatedAdministrationException(realm, ExternalResource.class.getSimpleName(), key);
+        }
+    }
+
     @PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_CREATE + "')")
     public ResourceTO create(final ResourceTO resourceTO) {
         if (StringUtils.isBlank(resourceTO.getKey())) {
@@ -121,7 +139,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw sce;
         }
 
-        if (resourceDAO.find(resourceTO.getKey()) != null) {
+        ConnInstance connInstance = connInstanceDAO.authFind(resourceTO.getConnector());
+        if (connInstance == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidExternalResource);
+            sce.getElements().add("Connector " + resourceTO.getConnector());
+            throw sce;
+        }
+
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_CREATE),
+                connInstance.getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, connInstance.getAdminRealm().getFullPath(), null);
+
+        if (resourceDAO.authFind(resourceTO.getKey()) != null) {
             throw new DuplicateException(resourceTO.getKey());
         }
 
@@ -130,17 +160,22 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
     @PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
     public ResourceTO update(final ResourceTO resourceTO) {
-        ExternalResource resource = resourceDAO.find(resourceTO.getKey());
+        ExternalResource resource = resourceDAO.authFind(resourceTO.getKey());
         if (resource == null) {
             throw new NotFoundException("Resource '" + resourceTO.getKey() + "'");
         }
 
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+                resource.getConnector().getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
         return binder.getResourceTO(resourceDAO.save(binder.update(resource, resourceTO)));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
     public void setLatestSyncToken(final String key, final String anyTypeKey) {
-        ExternalResource resource = resourceDAO.find(key);
+        ExternalResource resource = resourceDAO.authFind(key);
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
@@ -153,6 +188,11 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
         }
 
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+                resource.getConnector().getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
         Connector connector;
         try {
             connector = connFactory.getConnector(resource);
@@ -168,7 +208,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
     @PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_UPDATE + "')")
     public void removeSyncToken(final String key, final String anyTypeKey) {
-        ExternalResource resource = resourceDAO.find(key);
+        ExternalResource resource = resourceDAO.authFind(key);
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
@@ -181,17 +221,27 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
         }
 
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+                resource.getConnector().getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
         provision.setSyncToken(null);
         resourceDAO.save(resource);
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_DELETE + "')")
     public ResourceTO delete(final String key) {
-        ExternalResource resource = resourceDAO.find(key);
+        ExternalResource resource = resourceDAO.authFind(key);
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
 
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_DELETE),
+                resource.getConnector().getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
         ResourceTO resourceToDelete = binder.getResourceTO(resource);
 
         resourceDAO.delete(key);
@@ -202,7 +252,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     @PreAuthorize("hasRole('" + StandardEntitlement.RESOURCE_READ + "')")
     @Transactional(readOnly = true)
     public ResourceTO read(final String key) {
-        ExternalResource resource = resourceDAO.find(key);
+        ExternalResource resource = resourceDAO.authFind(key);
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
@@ -225,7 +275,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private Triple<ExternalResource, AnyType, Provision> connObjectInit(
             final String resourceKey, final String anyTypeKey) {
 
-        ExternalResource resource = resourceDAO.find(resourceKey);
+        ExternalResource resource = resourceDAO.authFind(resourceKey);
         if (resource == null) {
             throw new NotFoundException("Resource '" + resourceKey + "'");
         }
@@ -305,7 +355,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         ObjectClass objectClass;
         OperationOptions options;
         if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
-            resource = resourceDAO.find(key);
+            resource = resourceDAO.authFind(key);
             if (resource == null) {
                 throw new NotFoundException("Resource '" + key + "'");
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 54a43f3..ee68a4e 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -55,6 +55,7 @@ import org.apache.syncope.core.provisioning.api.LogicActions;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -95,8 +96,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
     @Transactional(readOnly = true)
     @Override
     public int count(final String realm) {
-        return userDAO.count(
-                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm));
+        return userDAO.count(RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm));
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.USER_SEARCH + "')")
@@ -106,9 +107,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
             final int page, final int size, final List<OrderByClause> orderBy,
             final String realm, final boolean details) {
 
-        return CollectionUtils.collect(userDAO.findAll(
-                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
-                page, size, orderBy),
+        return CollectionUtils.collect(userDAO.findAll(RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm), page, size, orderBy),
                 new Transformer<User, UserTO>() {
 
             @Transactional(readOnly = true)
@@ -138,8 +138,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
     @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final String realm) {
-        return searchDAO.count(
-                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
+        return searchDAO.count(RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
                 searchCondition, AnyTypeKind.USER);
     }
 
@@ -149,8 +149,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
     public List<UserTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final String realm, final boolean details) {
 
-        List<User> matchingUsers = searchDAO.search(
-                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
+        List<User> matchingUsers = searchDAO.search(RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_SEARCH), realm),
                 searchCondition, page, size, orderBy, AnyTypeKind.USER);
         return CollectionUtils.collect(matchingUsers, new Transformer<User, UserTO>() {
 
@@ -195,7 +195,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
         }
 
         if (!self) {
-            Set<String> effectiveRealms = getEffectiveRealms(
+            Set<String> effectiveRealms = RealmUtils.getEffective(
                     AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_CREATE),
                     before.getLeft().getRealm());
             securityChecks(effectiveRealms, before.getLeft().getRealm(), null);
@@ -233,7 +233,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
                 && before.getLeft().getRealm() != null
                 && StringUtils.isNotBlank(before.getLeft().getRealm().getValue())) {
 
-            Set<String> effectiveRealms = getEffectiveRealms(
+            Set<String> effectiveRealms = RealmUtils.getEffective(
                     AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                     before.getLeft().getRealm().getValue());
             authDynRealms =
@@ -278,7 +278,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
     public ProvisioningResult<UserTO> status(final StatusPatch statusPatch, final boolean nullPriorityAsync) {
         // security checks
         UserTO toUpdate = binder.getUserTO(statusPatch.getKey());
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 toUpdate.getRealm());
         securityChecks(effectiveRealms, toUpdate.getRealm(), toUpdate.getKey());
@@ -354,7 +354,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
         Pair<UserTO, List<LogicActions>> before = beforeDelete(userTO);
 
         if (!self) {
-            Set<String> effectiveRealms = getEffectiveRealms(
+            Set<String> effectiveRealms = RealmUtils.getEffective(
                     AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_DELETE),
                     before.getLeft().getRealm());
             securityChecks(effectiveRealms, before.getLeft().getRealm(), before.getLeft().getKey());
@@ -391,7 +391,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
     public UserTO unlink(final String key, final Collection<String> resources) {
         // security checks
         UserTO user = binder.getUserTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 user.getRealm());
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -414,7 +414,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
     public UserTO link(final String key, final Collection<String> resources) {
         // security checks
         UserTO user = binder.getUserTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 user.getRealm());
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -439,7 +439,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
 
         // security checks
         UserTO user = binder.getUserTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 user.getRealm());
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -468,7 +468,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
 
         // security checks
         UserTO user = binder.getUserTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 user.getRealm());
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -498,7 +498,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
 
         // security checks
         UserTO user = binder.getUserTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 user.getRealm());
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());
@@ -522,7 +522,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserPatch> {
 
         // security checks
         UserTO user = binder.getUserTO(key);
-        Set<String> effectiveRealms = getEffectiveRealms(
+        Set<String> effectiveRealms = RealmUtils.getEffective(
                 AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_UPDATE),
                 user.getRealm());
         securityChecks(effectiveRealms, user.getRealm(), user.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
index a7ba370..bb27896 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ConnInstanceDAO.java
@@ -25,6 +25,8 @@ public interface ConnInstanceDAO extends DAO<ConnInstance> {
 
     ConnInstance find(String key);
 
+    ConnInstance authFind(String key);
+
     List<ConnInstance> findAll();
 
     ConnInstance save(ConnInstance connector);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
index 6afa771..b48fd79 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
@@ -30,16 +30,14 @@ public interface ExternalResourceDAO extends DAO<ExternalResource> {
 
     ExternalResource find(String key);
 
+    ExternalResource authFind(String key);
+
     List<Provision> findProvisionsByAuxClass(AnyTypeClass anyTypeClass);
 
     List<ExternalResource> findByPolicy(Policy policy);
 
-    List<ExternalResource> findWithoutPolicy(Class<? extends Policy> policyClass);
-
     List<ExternalResource> findAll();
 
-    List<ExternalResource> findAllByPriority();
-
     ExternalResource save(ExternalResource resource);
 
     void deleteMapping(String schemaName);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
index 90650a2..908bb39 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
@@ -26,6 +26,10 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface ConnInstance extends Entity {
 
+    Realm getAdminRealm();
+
+    void setAdminRealm(Realm adminRealm);
+
     void setConnectorName(String connectorName);
 
     String getConnectorName();

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 3cf4376..b052f30 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -148,7 +148,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
         }
         if (authRealms == null || authRealms.isEmpty() || !authorized) {
             throw new DelegatedAdministrationException(
-                    anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+                    anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT.name(), anyObject.getKey());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index 8972b8b..7d4c0c8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -18,11 +18,17 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.api.dao.ConnInstanceHistoryConfDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -31,6 +37,8 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
@@ -52,10 +60,54 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance> implements Con
     }
 
     @Override
+    public ConnInstance authFind(final String key) {
+        final ConnInstance connInstance = find(key);
+        if (connInstance == null) {
+            return null;
+        }
+
+        final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_READ);
+        if (authRealms == null || authRealms.isEmpty()
+                || !IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+                    @Override
+                    public boolean evaluate(final String realm) {
+                        return connInstance.getAdminRealm().getFullPath().startsWith(realm);
+                    }
+                })) {
+
+            throw new DelegatedAdministrationException(
+                    connInstance.getAdminRealm().getFullPath(),
+                    ConnInstance.class.getSimpleName(),
+                    connInstance.getKey());
+        }
+
+        return connInstance;
+    }
+
+    @Override
     public List<ConnInstance> findAll() {
+        final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.CONNECTOR_LIST);
+        if (authRealms == null || authRealms.isEmpty()) {
+            return Collections.emptyList();
+        }
+
         TypedQuery<ConnInstance> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAConnInstance.class.getSimpleName() + " e", ConnInstance.class);
-        return query.getResultList();
+
+        return CollectionUtils.select(query.getResultList(), new Predicate<ConnInstance>() {
+
+            @Override
+            public boolean evaluate(final ConnInstance connInstance) {
+                return IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+                    @Override
+                    public boolean evaluate(final String realm) {
+                        return connInstance.getAdminRealm().getFullPath().startsWith(realm);
+                    }
+                });
+            }
+        }, new ArrayList<ConnInstance>());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index c49bd5a..8989fc5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -23,6 +23,9 @@ import java.util.List;
 import java.util.Set;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -53,6 +56,8 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
@@ -165,6 +170,33 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
     }
 
     @Override
+    public ExternalResource authFind(final String key) {
+        final ExternalResource resource = find(key);
+        if (resource == null) {
+            return null;
+        }
+
+        final Set<String> authRealms = AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_READ);
+        if (authRealms == null || authRealms.isEmpty()
+                || !IterableUtils.matchesAny(authRealms, new Predicate<String>() {
+
+                    @Override
+                    public boolean evaluate(final String realm) {
+                        return resource.getConnector() != null
+                                && resource.getConnector().getAdminRealm().getFullPath().startsWith(realm);
+                    }
+                })) {
+
+            throw new DelegatedAdministrationException(
+                    resource.getConnector().getAdminRealm().getFullPath(),
+                    ExternalResource.class.getSimpleName(),
+                    resource.getKey());
+        }
+
+        return resource;
+    }
+
+    @Override
     public List<Provision> findProvisionsByAuxClass(final AnyTypeClass anyTypeClass) {
         TypedQuery<Provision> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAProvision.class.getSimpleName()
@@ -193,19 +225,12 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
     @Override
     public List<ExternalResource> findByPolicy(final Policy policy) {
         TypedQuery<ExternalResource> query = entityManager().createQuery(
-                getByPolicyQuery(policy.getClass()).append(" = :policy").toString(), ExternalResource.class);
+                getByPolicyQuery(policy.getClass()).append("=:policy").toString(), ExternalResource.class);
         query.setParameter("policy", policy);
         return query.getResultList();
     }
 
     @Override
-    public List<ExternalResource> findWithoutPolicy(final Class<? extends Policy> policyClass) {
-        TypedQuery<ExternalResource> query = entityManager().createQuery(
-                getByPolicyQuery(policyClass).append(" IS NULL").toString(), ExternalResource.class);
-        return query.getResultList();
-    }
-
-    @Override
     public List<ExternalResource> findAll() {
         TypedQuery<ExternalResource> query = entityManager().createQuery(
                 "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
@@ -213,14 +238,6 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
     }
 
     @Override
-    public List<ExternalResource> findAllByPriority() {
-        TypedQuery<ExternalResource> query = entityManager().createQuery(
-                "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
-                ExternalResource.class);
-        return query.getResultList();
-    }
-
-    @Override
     @Transactional(rollbackFor = { Throwable.class })
     public ExternalResource save(final ExternalResource resource) {
         ExternalResource merged = entityManager().merge(resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9779e13e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 4c79d1b..4fb49e1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -172,7 +172,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
         if (authRealms == null || authRealms.isEmpty() || !authorized) {
             throw new DelegatedAdministrationException(
-                    group.getRealm().getFullPath(), AnyTypeKind.GROUP, group.getKey());
+                    group.getRealm().getFullPath(), AnyTypeKind.GROUP.name(), group.getKey());
         }
     }