You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2020/03/04 10:24:15 UTC

[syncope] branch SYNCOPE-163-1 updated: Fixes for Access policy and Authentication policy, added IT for both policies

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

skylark17 pushed a commit to branch SYNCOPE-163-1
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/SYNCOPE-163-1 by this push:
     new 0f7b7d2  Fixes for Access policy and Authentication policy, added IT for both policies
0f7b7d2 is described below

commit 0f7b7d201c92b1f4ab60364222c5aed8d933cbea
Author: skylark17 <sk...@apache.org>
AuthorDate: Wed Mar 4 10:13:09 2020 +0100

    Fixes for Access policy and Authentication policy, added IT for both policies
---
 .../authentication/AbstractAccessPolicyConf.java   |   3 +-
 .../AbstractAuthenticationPolicyConf.java          |   4 +-
 .../lib/authentication/AccessPolicyConf.java       |   3 +-
 .../authentication/AuthenticationModuleConf.java   |   1 -
 .../authentication/AuthenticationPolicyConf.java   |   2 +-
 .../authentication/DefaultAccessPolicyConf.java    |   7 +-
 .../DefaultAuthenticationPolicyConf.java           |   7 +-
 .../syncope/common/lib/policy/AccessPolicyTO.java  |   3 +-
 .../common/lib/policy/AuthenticationPolicyTO.java  |   1 -
 .../apache/syncope/common/lib/to/ResourceTO.java   |  26 +++
 .../init/ClassPathScanImplementationLookup.java    | 141 ++++++++++++++++
 .../core/persistence/api/dao/PolicyDAO.java        |   6 +
 .../syncope/core/persistence/api/entity/Realm.java |  11 +-
 .../api/entity/resource/ExternalResource.java      |  10 ++
 .../src/test/resources/domains/MasterContent.xml   |  15 ++
 .../jpa/dao/JPAExternalResourceDAO.java            |   6 +
 .../core/persistence/jpa/dao/JPAPolicyDAO.java     |  50 ++++--
 .../core/persistence/jpa/dao/JPARealmDAO.java      |   3 +
 .../authentication/JPAAuthenticationPolicyDAO.java |   4 +-
 .../core/persistence/jpa/entity/JPARealm.java      |  32 ++++
 .../jpa/entity/policy/JPAAccessPolicy.java         |  14 +-
 .../jpa/entity/policy/JPAAuthenticationPolicy.java |  14 +-
 .../jpa/entity/resource/JPAExternalResource.java   |  32 ++++
 .../jpa/inner/AuthenticationPolicyTest.java        |   6 +-
 .../persistence/jpa/inner/ImplementationTest.java  |   8 +-
 .../src/test/resources/domains/MasterContent.xml   |  20 ++-
 .../java/data/ImplementationDataBinderImpl.java    |  20 ++-
 .../java/data/PolicyDataBinderImpl.java            |  28 ++++
 .../java/data/ResourceDataBinderImpl.java          |  14 ++
 .../org/apache/syncope/fit/core/PolicyITCase.java  | 183 +++++++++++++++++++--
 30 files changed, 600 insertions(+), 74 deletions(-)

diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAccessPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAccessPolicyConf.java
index 3e4ed98..d0eb6d0 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAccessPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAccessPolicyConf.java
@@ -18,14 +18,15 @@
  */
 package org.apache.syncope.common.lib.authentication;
 
+import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
-
 import java.io.Serializable;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 @XmlType
+@XmlSeeAlso({ DefaultAccessPolicyConf.class })
 public abstract class AbstractAccessPolicyConf implements Serializable, AccessPolicyConf {
 
     private static final long serialVersionUID = 1153200197344709778L;
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java
index fc9352b..1fa4367 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java
@@ -16,16 +16,14 @@
  * under the License.
  *
  */
-
 package org.apache.syncope.common.lib.authentication;
 
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
-
 import java.io.Serializable;
 
 @XmlType
-@XmlSeeAlso({DefaultAuthenticationPolicyConf.class})
+@XmlSeeAlso({ DefaultAuthenticationPolicyConf.class })
 public abstract class AbstractAuthenticationPolicyConf implements Serializable, AuthenticationPolicyConf {
 
     private static final long serialVersionUID = 9185127128182430142L;
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AccessPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AccessPolicyConf.java
index c8a30c0..d5702bb 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AccessPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AccessPolicyConf.java
@@ -16,17 +16,16 @@
  * under the License.
  *
  */
-
 package org.apache.syncope.common.lib.authentication;
 
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
 import java.io.Serializable;
 import java.util.List;
 import java.util.Map;
 
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
 public interface AccessPolicyConf extends Serializable {
+
     /**
      * Give name of related access policy.
      *
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java
index 6211915..77a8d6a 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.common.lib.authentication;
 
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
 import java.io.Serializable;
 
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java
index c8e0557..f8e62aa 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java
@@ -19,9 +19,9 @@
 package org.apache.syncope.common.lib.authentication;
 
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
 import java.io.Serializable;
 
+@FunctionalInterface
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
 public interface AuthenticationPolicyConf extends Serializable {
 
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAccessPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAccessPolicyConf.java
index ea0fa79..643f4f2 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAccessPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAccessPolicyConf.java
@@ -16,14 +16,15 @@
  * under the License.
  *
  */
-
 package org.apache.syncope.common.lib.authentication;
 
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-@XmlRootElement(name = "defaultAuthenticationModuleConf")
+@XmlRootElement(name = "DefaultAccessPolicyConf")
 @XmlType
-public class DefaultAccessPolicyConf extends AbstractAccessPolicyConf {
+public class DefaultAccessPolicyConf extends AbstractAccessPolicyConf implements AccessPolicyConf {
+
     private static final long serialVersionUID = -1969836600059025380L;
+
 }
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java
index 7142a3c..bd190c7 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java
@@ -16,7 +16,6 @@
  * under the License.
  *
  */
-
 package org.apache.syncope.common.lib.authentication;
 
 import javax.xml.bind.annotation.XmlRootElement;
@@ -25,9 +24,11 @@ import javax.xml.bind.annotation.XmlType;
 import java.util.ArrayList;
 import java.util.List;
 
-@XmlRootElement(name = "defaultAuthenticationModuleConf")
+@XmlRootElement(name = "DefaultAuthenticationPolicyConf")
 @XmlType
-public class DefaultAuthenticationPolicyConf extends AbstractAuthenticationPolicyConf {
+public class DefaultAuthenticationPolicyConf extends AbstractAuthenticationPolicyConf
+        implements AuthenticationPolicyConf {
+
     private static final long serialVersionUID = -2969836600059025380L;
 
     private List<String> authenticationModules = new ArrayList<>();
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyTO.java
index 6a6306a..768fc68 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyTO.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AccessPolicyTO.java
@@ -16,12 +16,10 @@
  * under the License.
  *
  */
-
 package org.apache.syncope.common.lib.policy;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
-
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
@@ -29,6 +27,7 @@ import javax.xml.bind.annotation.XmlType;
 @XmlRootElement(name = "accessPolicy")
 @XmlType
 public class AccessPolicyTO extends PolicyTO {
+
     private static final long serialVersionUID = -6711411162433533300L;
 
     @XmlTransient
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AuthenticationPolicyTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AuthenticationPolicyTO.java
index 6188f43..ede20e3 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AuthenticationPolicyTO.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/AuthenticationPolicyTO.java
@@ -20,7 +20,6 @@ package org.apache.syncope.common.lib.policy;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
-
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index 20a8628..4749fe4 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -82,6 +82,10 @@ public class ResourceTO implements EntityTO {
 
     private String provisionSorter;
 
+    private String authenticationPolicy;
+
+    private String accessPolicy;
+
     private final List<ConnConfProperty> confOverride = new ArrayList<>();
 
     private boolean overrideCapabilities = false;
@@ -205,6 +209,22 @@ public class ResourceTO implements EntityTO {
         this.provisionSorter = provisionSorter;
     }
 
+    public String getAuthenticationPolicy() {
+        return authenticationPolicy;
+    }
+
+    public void setAuthenticationPolicy(final String authenticationPolicy) {
+        this.authenticationPolicy = authenticationPolicy;
+    }
+
+    public String getAccessPolicy() {
+        return accessPolicy;
+    }
+
+    public void setAccessPolicy(final String accessPolicy) {
+        this.accessPolicy = accessPolicy;
+    }
+
     @JsonIgnore
     public Optional<ProvisionTO> getProvision(final String anyType) {
         return provisions.stream().filter(
@@ -294,9 +314,12 @@ public class ResourceTO implements EntityTO {
                 append(accountPolicy, other.accountPolicy).
                 append(pullPolicy, other.pullPolicy).
                 append(pushPolicy, other.pushPolicy).
+                append(authenticationPolicy, other.authenticationPolicy).
+                append(accessPolicy, other.accessPolicy).
                 append(confOverride, other.confOverride).
                 append(capabilitiesOverride, other.capabilitiesOverride).
                 append(propagationActions, other.propagationActions).
+                append(provisionSorter, other.provisionSorter).
                 build();
     }
 
@@ -319,10 +342,13 @@ public class ResourceTO implements EntityTO {
                 append(accountPolicy).
                 append(pullPolicy).
                 append(pushPolicy).
+                append(authenticationPolicy).
+                append(accessPolicy).
                 append(confOverride).
                 append(overrideCapabilities).
                 append(capabilitiesOverride).
                 append(propagationActions).
+                append(provisionSorter).
                 build();
     }
 }
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
new file mode 100644
index 0000000..c9d7fea
--- /dev/null
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -0,0 +1,141 @@
+/*
+ * 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.logic.init;
+
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import org.apache.syncope.common.lib.authentication.AccessPolicyConf;
+import org.apache.syncope.common.lib.authentication.AuthenticationModuleConf;
+import org.apache.syncope.common.lib.authentication.AuthenticationPolicyConf;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
+import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.core.Ordered;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.
+ */
+public class ClassPathScanImplementationLookup implements SyncopeCoreLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ImplementationLookup.class);
+
+    private static final String DEFAULT_BASE_PACKAGE = "org.apache.syncope.core";
+
+    private Map<String, Set<String>> classNames;
+
+    private Map<Class<? extends AuthenticationPolicyConf>, Class<? extends AuthenticationPolicyConf>> authPolicyClasses;
+
+    private Map<Class<? extends AuthenticationModuleConf>, Class<? extends AuthenticationModuleConf>> authModuleClasses;
+
+    private Map<Class<? extends AccessPolicyConf>, Class<? extends AccessPolicyConf>> accessPolicyClasses;
+
+    @Override
+    public int getOrder() {
+        return Ordered.HIGHEST_PRECEDENCE;
+    }
+
+    /**
+     * This method can be overridden by subclasses to customize classpath scan.
+     *
+     * @return basePackage for classpath scanning
+     */
+    protected static String getBasePackage() {
+        return DEFAULT_BASE_PACKAGE;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void load() {
+        classNames = new HashMap<>();
+        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+        ImplementationTypesHolder.getInstance().getValues().forEach((typeName, typeInterface) -> {
+            classNames.put(typeName, new HashSet<>());
+            try {
+                scanner.addIncludeFilter(new AssignableTypeFilter(
+                        ClassUtils.resolveClassName(typeInterface, ClassUtils.getDefaultClassLoader())));
+            } catch (IllegalArgumentException e) {
+                LOG.error("Could not find class, ignoring...", e);
+            }
+        });
+
+        authPolicyClasses = new HashMap<>();
+        authModuleClasses = new HashMap<>();
+        accessPolicyClasses = new HashMap<>();
+
+        scanner.findCandidateComponents(getBasePackage()).forEach(bd -> {
+            try {
+                Class<?> clazz = ClassUtils.resolveClassName(
+                        Objects.requireNonNull(bd.getBeanClassName()), ClassUtils.getDefaultClassLoader());
+                boolean isAbstractClazz = Modifier.isAbstract(clazz.getModifiers());
+
+                if (AuthenticationPolicyConf.class.isAssignableFrom(clazz) && !isAbstractClazz) {
+                    classNames.get(AMImplementationType.AUTH_POLICY_CONFIGURATIONS).add(bd.getBeanClassName());
+                }
+                if (AuthenticationModuleConf.class.isAssignableFrom(clazz) && !isAbstractClazz) {
+                    classNames.get(AMImplementationType.AUTH_MODULE_CONFIGURATIONS).add(bd.getBeanClassName());
+                }
+                if (AccessPolicyConf.class.isAssignableFrom(clazz) && !isAbstractClazz) {
+                    classNames.get(AMImplementationType.ACCESS_POLICY_CONFIGURATIONS).add(bd.getBeanClassName());
+                }
+            } catch (Throwable t) {
+                LOG.warn("Could not inspect class {}", bd.getBeanClassName(), t);
+            }
+        });
+
+        classNames = Collections.unmodifiableMap(classNames);
+        LOG.debug("Implementation classes found: {}", classNames);
+
+        authPolicyClasses = Collections.unmodifiableMap(authPolicyClasses);
+        authModuleClasses = Collections.unmodifiableMap(authModuleClasses);
+        accessPolicyClasses = Collections.unmodifiableMap(accessPolicyClasses);
+    }
+
+    public Set<String> getClassNames(final String type) {
+        return classNames.get(type);
+    }
+
+    public Class<? extends AuthenticationPolicyConf> getAuthPolicyConfClass(
+            final Class<? extends AuthenticationPolicyConf> authPolicyConfClass) {
+
+        return authPolicyClasses.get(authPolicyConfClass);
+    }
+
+    public Class<? extends AuthenticationModuleConf> getAuthModuleConfClass(
+            final Class<? extends AuthenticationModuleConf> authModuleConfClass) {
+
+        return authModuleClasses.get(authModuleConfClass);
+    }
+
+    public Class<? extends AccessPolicyConf> getAccessPolicyConfClass(
+            final Class<? extends AccessPolicyConf> accessPolicyConfClass) {
+
+        return accessPolicyClasses.get(accessPolicyConfClass);
+    }
+}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
index 6765030..482ee4b 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
@@ -20,7 +20,9 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
@@ -43,6 +45,10 @@ public interface PolicyDAO extends DAO<Policy> {
 
     List<AccountPolicy> findByResource(ExternalResource resource);
 
+    List<AuthenticationPolicy> findByAuthenticationRule(Implementation authenticationRule);
+
+    List<AccessPolicy> findByAccessRule(Implementation accessRule);
+
     List<Policy> findAll();
 
     <T extends Policy> T save(T policy);
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
index f579702..6c7a542 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
@@ -21,9 +21,10 @@ package org.apache.syncope.core.persistence.api.entity;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-
 import java.util.List;
 import java.util.Optional;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 
 public interface Realm extends Entity {
 
@@ -45,6 +46,14 @@ public interface Realm extends Entity {
 
     void setPasswordPolicy(PasswordPolicy passwordPolicy);
 
+    void setAuthenticationPolicy(AuthenticationPolicy authenticationPolicy);
+
+    AuthenticationPolicy getAuthenticationPolicy();
+
+    void setAccessPolicy(AccessPolicy accessPolicy);
+
+    AccessPolicy getAccessPolicy();
+
     boolean add(Implementation action);
 
     List<? extends Implementation> getActions();
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
index 1bb44d9..d281fc8 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
@@ -29,6 +29,8 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
@@ -63,7 +65,15 @@ public interface ExternalResource extends ProvidedKeyEntity {
     void setPullPolicy(PullPolicy pullPolicy);
 
     PushPolicy getPushPolicy();
+
+    void setAuthenticationPolicy(AuthenticationPolicy authenticationPolicy);
+
+    AuthenticationPolicy getAuthenticationPolicy();
     
+    void setAccessPolicy(AccessPolicy accessPolicy);
+
+    AccessPolicy getAccessPolicy();
+
     Implementation getProvisionSorter();
 
     void setProvisionSorter(Implementation provisionSorter);
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index 7669c7b..5b28703 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -43,6 +43,21 @@ under the License.
   <Implementation id="DefaultPasswordRuleConf3" type="PASSWORD_RULE" engine="JAVA"
                   body='{"@class":"org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf","maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWit [...]
   <PasswordPolicyRule policy_id="55e5de0b-c79c-4e66-adda-251b6fb8579a" implementation_id="DefaultPasswordRuleConf3"/>
+  
+  <!-- authentication policies -->
+  <Implementation id="MyDefaultAuthenticationPolicyConf" type="AUTH_POLICY_CONFIGURATIONS" engine="JAVA"
+                  body='{"@class":"org.apache.syncope.common.lib.authentication.DefaultAuthenticationPolicyConf","authenticationModules":["LdapAuthenticationTest"]}'/>
+  <AuthenticationPolicy id="659b9906-4b6e-4bc0-aca0-6809dff346d4" name="MyDefaultAuthenticationPolicyConf" 
+                        description="an authentication policy" />
+  <AuthenticationPolicy id="b912a0d4-a890-416f-9ab8-84ab077eb028" name="DefaultAuthenticationPolicy" 
+                        description="Default authentication policy"/>
+  <AuthenticationModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultAuthenticationModule"/>
+  
+  <!-- access policies -->
+  <Implementation id="MyDefaultAccessPolicyConf" type="ACCESS_POLICY_CONFIGURATIONS" engine="JAVA"
+                  body='{"@class":"org.apache.syncope.common.lib.authentication.DefaultAccessPolicyConf","name":"MyDefaultAccessPolicyConf","enabled":true,"singleSignOnEnabled":true}'/>
+  <AccessPolicy id="419935c7-deb3-40b3-8a9a-683037e523a2" name="MyDefaultAccessPolicyConf"
+                description="an access policy" />
 
   <RelationshipType id="inclusion" description="Models the act that an object is included in another"/>
   <RelationshipType id="neighborhood" description="Models the act that an object is near another"/>
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 a76f49f..10ea313 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
@@ -38,7 +38,9 @@ import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
@@ -160,6 +162,10 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
             query.append("pullPolicy");
         } else if (PushPolicy.class.isAssignableFrom(policyClass)) {
             query.append("pushPolicy");
+        } else if (AuthenticationPolicy.class.isAssignableFrom(policyClass)) {
+            query.append("authenticationPolicy");
+        } else if (AccessPolicy.class.isAssignableFrom(policyClass)) {
+            query.append("accessPolicy");
         }
 
         return query;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
index b295743..fd7728f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
@@ -144,6 +144,26 @@ public class JPAPolicyDAO extends AbstractDAO<Policy> implements PolicyDAO {
     }
 
     @Override
+    public List<AuthenticationPolicy> findByAuthenticationRule(final Implementation authenticationRule) {
+        TypedQuery<AuthenticationPolicy> query = entityManager().createQuery(
+                "SELECT e FROM " + JPAAuthenticationPolicy.class.getSimpleName() + " e "
+                + "WHERE :authenticationRule MEMBER OF e.rules", AuthenticationPolicy.class);
+        query.setParameter("authenticationRule", authenticationRule);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public List<AccessPolicy> findByAccessRule(final Implementation accessRule) {
+        TypedQuery<AccessPolicy> query = entityManager().createQuery(
+                "SELECT e FROM " + JPAAccessPolicy.class.getSimpleName() + " e "
+                + "WHERE :accessRule MEMBER OF e.rules", AccessPolicy.class);
+        query.setParameter("accessRule", accessRule);
+
+        return query.getResultList();
+    }
+
+    @Override
     public <T extends Policy> T save(final T policy) {
         return entityManager().merge(policy);
     }
@@ -155,22 +175,26 @@ public class JPAPolicyDAO extends AbstractDAO<Policy> implements PolicyDAO {
                 realm.setAccountPolicy(null);
             } else if (policy instanceof PasswordPolicy) {
                 realm.setPasswordPolicy(null);
+            } else if (policy instanceof AuthenticationPolicy) {
+                realm.setAuthenticationPolicy(null);
             }
         });
 
-        if (!(policy instanceof AuthenticationPolicy) && !(policy instanceof AccessPolicy)) {
-            resourceDAO.findByPolicy(policy).forEach(resource -> {
-                if (policy instanceof AccountPolicy) {
-                    resource.setAccountPolicy(null);
-                } else if (policy instanceof PasswordPolicy) {
-                    resource.setPasswordPolicy(null);
-                } else if (policy instanceof PullPolicy) {
-                    resource.setPullPolicy(null);
-                } else if (policy instanceof PushPolicy) {
-                    resource.setPushPolicy(null);
-                }
-            });
-        }
+        resourceDAO.findByPolicy(policy).forEach(resource -> {
+            if (policy instanceof AccountPolicy) {
+                resource.setAccountPolicy(null);
+            } else if (policy instanceof PasswordPolicy) {
+                resource.setPasswordPolicy(null);
+            } else if (policy instanceof PullPolicy) {
+                resource.setPullPolicy(null);
+            } else if (policy instanceof PushPolicy) {
+                resource.setPushPolicy(null);
+            } else if (policy instanceof AuthenticationPolicy) {
+                resource.setAuthenticationPolicy(null);
+            } else if (policy instanceof AccessPolicy) {
+                resource.setAccessPolicy(null);
+            }
+        });
 
         entityManager().remove(policy);
     }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index 5022207..e3c60a1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -32,6 +32,7 @@ import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
@@ -155,6 +156,8 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
             policyColumn = "passwordPolicy";
         } else if (policy instanceof AuthenticationPolicy) {
             policyColumn = "authenticationPolicy";
+        } else if (policy instanceof AccessPolicy) {
+            policyColumn = "accessPolicy";
         }
 
         TypedQuery<Realm> query = entityManager().createQuery(
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/authentication/JPAAuthenticationPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/authentication/JPAAuthenticationPolicyDAO.java
index 388b7f2..452102b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/authentication/JPAAuthenticationPolicyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/authentication/JPAAuthenticationPolicyDAO.java
@@ -24,9 +24,7 @@ import org.apache.syncope.core.persistence.jpa.dao.AbstractDAO;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthenticationPolicy;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
-
 import javax.persistence.TypedQuery;
-
 import java.util.List;
 
 @Repository
@@ -41,7 +39,7 @@ public class JPAAuthenticationPolicyDAO extends AbstractDAO<AuthenticationPolicy
     @Override
     public List<AuthenticationPolicy> findAll() {
         TypedQuery<AuthenticationPolicy> query = entityManager().createQuery(
-            "SELECT e FROM " + JPAAuthenticationPolicy.class.getSimpleName() + " e", AuthenticationPolicy.class);
+                "SELECT e FROM " + JPAAuthenticationPolicy.class.getSimpleName() + " e", AuthenticationPolicy.class);
 
         return query.getResultList();
     }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
index 129fd1c..79a6dfa 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
@@ -50,6 +50,10 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccessPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthenticationPolicy;
 
 @Entity
 @Table(name = JPARealm.TABLE, uniqueConstraints =
@@ -74,6 +78,12 @@ public class JPARealm extends AbstractGeneratedKeyEntity implements Realm {
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAAccountPolicy accountPolicy;
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAuthenticationPolicy authenticationPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAccessPolicy accessPolicy;
+
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(name = TABLE + "Action",
             joinColumns =
@@ -147,6 +157,28 @@ public class JPARealm extends AbstractGeneratedKeyEntity implements Realm {
     }
 
     @Override
+    public AuthenticationPolicy getAuthenticationPolicy() {
+        return authenticationPolicy;
+    }
+
+    @Override
+    public void setAuthenticationPolicy(final AuthenticationPolicy authenticationPolicy) {
+        checkType(authenticationPolicy, JPAAuthenticationPolicy.class);
+        this.authenticationPolicy = (JPAAuthenticationPolicy) authenticationPolicy;
+    }
+
+    @Override
+    public AccessPolicy getAccessPolicy() {
+        return accessPolicy;
+    }
+
+    @Override
+    public void setAccessPolicy(final AccessPolicy accessPolicy) {
+        checkType(accessPolicy, JPAAccessPolicy.class);
+        this.accessPolicy = (JPAAccessPolicy) accessPolicy;
+    }
+
+    @Override
     public boolean add(final Implementation action) {
         checkType(action, JPAImplementation.class);
         checkImplementationType(action, IdRepoImplementationType.LOGIC_ACTIONS);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
index ed432ba..63e83b6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
@@ -48,12 +48,12 @@ public class JPAAccessPolicy extends AbstractPolicy implements AccessPolicy {
 
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(name = TABLE + "Conf",
-        joinColumns =
-        @JoinColumn(name = "authentication_policy_id"),
-        inverseJoinColumns =
-        @JoinColumn(name = "implementation_id"),
-        uniqueConstraints =
-        @UniqueConstraint(columnNames = {"authentication_policy_id", "implementation_id"}))
+            joinColumns =
+            @JoinColumn(name = "authentication_policy_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "implementation_id"),
+            uniqueConstraints =
+            @UniqueConstraint(columnNames = { "authentication_policy_id", "implementation_id" }))
     private List<JPAImplementation> configurations = new ArrayList<>();
 
     @Override
@@ -76,6 +76,6 @@ public class JPAAccessPolicy extends AbstractPolicy implements AccessPolicy {
         checkType(configuration, JPAImplementation.class);
         checkImplementationType(configuration, AMImplementationType.ACCESS_POLICY_CONFIGURATIONS);
         return configurations.contains((JPAImplementation) configuration)
-            || configurations.add((JPAImplementation) configuration);
+                || configurations.add((JPAImplementation) configuration);
     }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthenticationPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthenticationPolicy.java
index f015063..f0125b3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthenticationPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthenticationPolicy.java
@@ -48,12 +48,12 @@ public class JPAAuthenticationPolicy extends AbstractPolicy implements Authentic
 
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(name = TABLE + "Conf",
-        joinColumns =
-        @JoinColumn(name = "authentication_policy_id"),
-        inverseJoinColumns =
-        @JoinColumn(name = "implementation_id"),
-        uniqueConstraints =
-        @UniqueConstraint(columnNames = {"authentication_policy_id", "implementation_id"}))
+            joinColumns =
+            @JoinColumn(name = "authentication_policy_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "implementation_id"),
+            uniqueConstraints =
+            @UniqueConstraint(columnNames = { "authentication_policy_id", "implementation_id" }))
     private List<JPAImplementation> configurations = new ArrayList<>();
 
     @Override
@@ -76,6 +76,6 @@ public class JPAAuthenticationPolicy extends AbstractPolicy implements Authentic
         checkType(configuration, JPAImplementation.class);
         checkImplementationType(configuration, AMImplementationType.AUTH_POLICY_CONFIGURATIONS);
         return configurations.contains((JPAImplementation) configuration)
-            || configurations.add((JPAImplementation) configuration);
+                || configurations.add((JPAImplementation) configuration);
     }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
index ef97aa6..64a150c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -53,6 +53,8 @@ import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourc
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
@@ -64,6 +66,8 @@ import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractProvidedKeyEntity;
 import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccessPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthenticationPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushPolicy;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 
@@ -136,6 +140,12 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAPushPolicy pushPolicy;
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAuthenticationPolicy authenticationPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAccessPolicy accessPolicy;
+
     @ManyToOne
     private JPAImplementation provisionSorter;
 
@@ -333,6 +343,28 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     }
 
     @Override
+    public AuthenticationPolicy getAuthenticationPolicy() {
+        return authenticationPolicy;
+    }
+
+    @Override
+    public void setAuthenticationPolicy(final AuthenticationPolicy authenticationPolicy) {
+        checkType(authenticationPolicy, JPAAuthenticationPolicy.class);
+        this.authenticationPolicy = (JPAAuthenticationPolicy) authenticationPolicy;
+    }
+
+    @Override
+    public AccessPolicy getAccessPolicy() {
+        return accessPolicy;
+    }
+
+    @Override
+    public void setAccessPolicy(final AccessPolicy accessPolicy) {
+        checkType(accessPolicy, JPAAccessPolicy.class);
+        this.accessPolicy = (JPAAccessPolicy) accessPolicy;
+    }
+
+    @Override
     public Implementation getProvisionSorter() {
         return provisionSorter;
     }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationPolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationPolicyTest.java
index af31ce9..4497144 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationPolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationPolicyTest.java
@@ -49,6 +49,8 @@ public class AuthenticationPolicyTest extends AbstractTest {
     public void find() {
         AuthenticationPolicy authenticationPolicy = authenticationPolicyDAO.find("b912a0d4-a890-416f-9ab8-84ab077eb028");
         assertNotNull(authenticationPolicy);
+        authenticationPolicy = authenticationPolicyDAO.find("659b9906-4b6e-4bc0-aca0-6809dff346d4");
+        assertNotNull(authenticationPolicy);
         authenticationPolicy = authenticationPolicyDAO.find(UUID.randomUUID().toString());
         assertNull(authenticationPolicy);
     }
@@ -57,7 +59,7 @@ public class AuthenticationPolicyTest extends AbstractTest {
     public void findAll() {
         List<AuthenticationPolicy> authenticationPolicies = authenticationPolicyDAO.findAll();
         assertNotNull(authenticationPolicies);
-        assertEquals(1, authenticationPolicies.size());
+        assertEquals(2, authenticationPolicies.size());
     }
 
     @Test
@@ -69,7 +71,7 @@ public class AuthenticationPolicyTest extends AbstractTest {
 
         DefaultAuthenticationPolicyConf conf = new DefaultAuthenticationPolicyConf();
         conf.setAuthenticationModules(List.of("LdapAuthentication1", "DatabaseAuthentication2"));
-        
+
         Implementation type = entityFactory.newEntity(Implementation.class);
         type.setKey("AuthPolicyConfKey");
         type.setEngine(ImplementationEngine.JAVA);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java
index 9fc9df7..aa36e68 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java
@@ -45,7 +45,7 @@ public class ImplementationTest extends AbstractTest {
         List<Implementation> implementations = implementationDAO.findAll();
         assertFalse(implementations.isEmpty());
 
-        assertEquals(18, implementations.size());
+        assertEquals(20, implementations.size());
 
         implementations = implementationDAO.findByType(IdMImplementationType.PULL_ACTIONS);
         assertEquals(1, implementations.size());
@@ -73,6 +73,12 @@ public class ImplementationTest extends AbstractTest {
 
         implementations = implementationDAO.findByType(IdMImplementationType.PUSH_CORRELATION_RULE);
         assertEquals(1, implementations.size());
+
+        implementations = implementationDAO.findByType(AMImplementationType.AUTH_POLICY_CONFIGURATIONS);
+        assertEquals(1, implementations.size());
+
+        implementations = implementationDAO.findByType(AMImplementationType.ACCESS_POLICY_CONFIGURATIONS);
+        assertEquals(1, implementations.size());
     }
 
     @Test
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 39020ab..560c330 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -43,6 +43,21 @@ under the License.
   <Implementation id="DefaultPasswordRuleConf3" type="PASSWORD_RULE" engine="JAVA"
                   body='{"@class":"org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf","maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWit [...]
   <PasswordPolicyRule policy_id="55e5de0b-c79c-4e66-adda-251b6fb8579a" implementation_id="DefaultPasswordRuleConf3"/>
+  
+  <!-- authentication policies -->
+  <Implementation id="MyDefaultAuthenticationPolicyConf" type="AUTH_POLICY_CONFIGURATIONS" engine="JAVA"
+                  body='{"@class":"org.apache.syncope.common.lib.authentication.DefaultAuthenticationPolicyConf","authenticationModules":["LdapAuthenticationTest"]}'/>
+  <AuthenticationPolicy id="659b9906-4b6e-4bc0-aca0-6809dff346d4" name="MyDefaultAuthenticationPolicyConf" 
+                        description="an authentication policy" />
+  <AuthenticationPolicy id="b912a0d4-a890-416f-9ab8-84ab077eb028" name="DefaultAuthenticationPolicy" 
+                        description="Default authentication policy"/>
+  <AuthenticationModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultAuthenticationModule"/>
+  
+  <!-- access policies -->
+  <Implementation id="MyDefaultAccessPolicyConf" type="ACCESS_POLICY_CONFIGURATIONS" engine="JAVA"
+                  body='{"@class":"org.apache.syncope.common.lib.authentication.DefaultAccessPolicyConf","name":"MyDefaultAccessPolicyConf","enabled":true,"singleSignOnEnabled":true}'/>
+  <AccessPolicy id="419935c7-deb3-40b3-8a9a-683037e523a2" name="MyDefaultAccessPolicyConf"
+                description="an access policy" />
 
   <RelationshipType id="inclusion" description="Models the act that an object is included in another"/>
   <RelationshipType id="neighborhood" description="Models the act that an object is near another"/>
@@ -500,7 +515,7 @@ under the License.
   
   <GPlainAttr id="22690472-ed3f-4972-8979-4c9251fab044" owner_id="ba9ed509-b1f5-48ab-a334-c8530a6422dc" schema_id="title"/>
   <GPlainAttrValue attribute_id="22690472-ed3f-4972-8979-4c9251fab044" id="e16765e6-f806-469e-ae34-1ddf56f2102a" stringValue="r13"/>
-
+  
   <!-- pull policies -->
   <PullPolicy id="66691e96-285f-4464-bc19-e68384ea4c85" description="a pull policy" conflictResolutionAction="IGNORE"/>
   <PullPolicy id="880f8553-069b-4aed-9930-2cd53873f544" description="another pull policy" conflictResolutionAction="ALL"/>
@@ -2469,7 +2484,4 @@ $$ }&#10;
   <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unlink]:[SUCCESS]" logLevel="DEBUG"/>
   <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[update]:[SUCCESS]" logLevel="DEBUG"/>
 
-  <AuthenticationPolicy id="b912a0d4-a890-416f-9ab8-84ab077eb028" name="DefaultAuthenticationPolicy" description="Default authentication policy"/>
-  <AuthenticationModule id="be456831-593d-4003-b273-4c3fb61700df" name="DefaultAuthenticationModule"/>
-
 </dataset>
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 ecc0332..af630fb 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
@@ -21,6 +21,9 @@ package org.apache.syncope.core.provisioning.java.data;
 import java.lang.reflect.Modifier;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.authentication.AccessPolicyConf;
+import org.apache.syncope.common.lib.authentication.AuthenticationModuleConf;
+import org.apache.syncope.common.lib.authentication.AuthenticationPolicyConf;
 import org.apache.syncope.common.lib.policy.RuleConf;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.to.ImplementationTO;
@@ -175,24 +178,25 @@ public class ImplementationDataBinderImpl implements ImplementationDataBinder {
 
             switch (implementation.getType()) {
                 case AMImplementationType.ACCESS_POLICY_CONFIGURATIONS:
-                    AccessPolicy accessPolicy = POJOHelper.deserialize(implementation.getBody(), AccessPolicy.class);
-                    if (accessPolicy == null) {
+                    AccessPolicyConf accessPolicyConf =
+                            POJOHelper.deserialize(implementation.getBody(), AccessPolicyConf.class);
+                    if (accessPolicyConf == null) {
                         sce.getElements().add("Could not deserialize as AccessPolicy");
                         throw sce;
                     }
                     break;
                 case AMImplementationType.AUTH_MODULE_CONFIGURATIONS:
-                    AuthenticationModule authenticationModule =
-                        POJOHelper.deserialize(implementation.getBody(), AuthenticationModule.class);
-                    if (authenticationModule == null) {
+                    AuthenticationModuleConf authenticationModuleConf =
+                            POJOHelper.deserialize(implementation.getBody(), AuthenticationModuleConf.class);
+                    if (authenticationModuleConf == null) {
                         sce.getElements().add("Could not deserialize as AuthenticationModule");
                         throw sce;
                     }
                     break;
                 case AMImplementationType.AUTH_POLICY_CONFIGURATIONS:
-                    AuthenticationPolicy authenticationPolicy =
-                        POJOHelper.deserialize(implementation.getBody(), AuthenticationPolicy.class);
-                    if (authenticationPolicy == null) {
+                    AuthenticationPolicyConf authenticationPolicyConf =
+                            POJOHelper.deserialize(implementation.getBody(), AuthenticationPolicyConf.class);
+                    if (authenticationPolicyConf == null) {
                         sce.getElements().add("Could not deserialize as AuthenticationPolicy");
                         throw sce;
                     }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index f4fbe76..159f15d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -19,9 +19,11 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.policy.AccessPolicyTO;
 import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
 import org.apache.syncope.common.lib.policy.PolicyTO;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
+import org.apache.syncope.common.lib.policy.AuthenticationPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
 import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.policy.PushPolicyTO;
@@ -38,6 +40,8 @@ import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
@@ -192,6 +196,24 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
             // remove all rules not contained in the TO
             pushPolicy.getCorrelationRules().removeIf(anyFilter
                     -> !pushPolicyTO.getCorrelationRules().containsKey(anyFilter.getAnyType().getKey()));
+        } else if (policyTO instanceof AuthenticationPolicyTO) {
+            if (result == null) {
+                result = (T) entityFactory.newEntity(AuthenticationPolicy.class);
+            }
+
+            AuthenticationPolicy authenticationPolicy = AuthenticationPolicy.class.cast(result);
+            AuthenticationPolicyTO authenticationPolicyTO = AuthenticationPolicyTO.class.cast(policyTO);
+
+            authenticationPolicy.setName(authenticationPolicyTO.getKey());
+        } else if (policyTO instanceof AccessPolicyTO) {
+            if (result == null) {
+                result = (T) entityFactory.newEntity(AccessPolicy.class);
+            }
+
+            AccessPolicy accessPolicy = AccessPolicy.class.cast(result);
+            AccessPolicyTO accessPolicyTO = AccessPolicyTO.class.cast(policyTO);
+
+            accessPolicy.setName(accessPolicyTO.getKey());
         }
 
         if (result != null) {
@@ -257,6 +279,12 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
             pushPolicy.getCorrelationRules().
                     forEach(rule -> pushPolicyTO.getCorrelationRules().
                     put(rule.getAnyType().getKey(), rule.getImplementation().getKey()));
+        } else if (policy instanceof AuthenticationPolicy) {
+            AuthenticationPolicyTO authenticationPolicyTO = new AuthenticationPolicyTO();
+            policyTO = (T) authenticationPolicyTO;
+        } else if (policy instanceof AccessPolicy) {
+            AccessPolicyTO accessPolicyTO = new AccessPolicyTO();
+            policyTO = (T) accessPolicyTO;
         }
 
         if (policyTO != null) {
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index 1df550e..b17517e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -61,6 +61,8 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.Item;
@@ -358,6 +360,12 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resource.setPushPolicy(resourceTO.getPushPolicy() == null
                 ? null : (PushPolicy) policyDAO.find(resourceTO.getPushPolicy()));
 
+        resource.setAuthenticationPolicy(resourceTO.getAuthenticationPolicy() == null
+                ? null : (AuthenticationPolicy) policyDAO.find(resourceTO.getAuthenticationPolicy()));
+
+        resource.setAccessPolicy(resourceTO.getAccessPolicy() == null
+                ? null : (AccessPolicy) policyDAO.find(resourceTO.getAccessPolicy()));
+
         if (resourceTO.getProvisionSorter() == null) {
             resource.setProvisionSorter(null);
         } else {
@@ -687,6 +695,12 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resourceTO.setPushPolicy(resource.getPushPolicy() == null
                 ? null : resource.getPushPolicy().getKey());
 
+        resourceTO.setAuthenticationPolicy(resource.getAuthenticationPolicy() == null
+                ? null : resource.getAuthenticationPolicy().getKey());
+
+        resourceTO.setAccessPolicy(resource.getAccessPolicy() == null
+                ? null : resource.getAccessPolicy().getKey());
+
         resourceTO.setProvisionSorter(resource.getProvisionSorter() == null
                 ? null : resource.getProvisionSorter().getKey());
 
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
index aa7773d..5b436b1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
@@ -33,6 +33,7 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.authentication.DefaultAccessPolicyConf;
 import org.apache.syncope.common.lib.authentication.DefaultAuthenticationPolicyConf;
 import org.apache.syncope.common.lib.policy.AccessPolicyTO;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
@@ -55,35 +56,75 @@ import org.apache.syncope.fit.AbstractITCase;
 import org.apache.syncope.fit.core.reference.DummyPullCorrelationRule;
 import org.apache.syncope.fit.core.reference.DummyPushCorrelationRule;
 import org.junit.jupiter.api.Test;
+import org.junit.platform.commons.util.StringUtils;
 
 public class PolicyITCase extends AbstractITCase {
 
     private static AuthenticationPolicyTO buildAuthenticationPolicyTO() {
+        final String authPolicyName = "TestAuthenticationPolicy" + getUUIDString();
+
         ImplementationTO implementationTO = null;
         try {
-            implementationTO = implementationService.read(AMImplementationType.AUTH_POLICY_CONFIGURATIONS, "TestAuthenticationPolicy");
+            implementationTO = implementationService.read(
+                    AMImplementationType.AUTH_POLICY_CONFIGURATIONS, authPolicyName);
         } catch (SyncopeClientException e) {
             if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) {
                 implementationTO = new ImplementationTO();
-                implementationTO.setKey("TestAuthenticationPolicy");
+                implementationTO.setKey(authPolicyName);
                 implementationTO.setEngine(ImplementationEngine.JAVA);
                 implementationTO.setType(AMImplementationType.AUTH_POLICY_CONFIGURATIONS);
 
                 DefaultAuthenticationPolicyConf conf = new DefaultAuthenticationPolicyConf();
                 conf.setAuthenticationModules(List.of("LdapAuthentication1"));
                 implementationTO.setBody(POJOHelper.serialize(conf));
-                
+
                 Response response = implementationService.create(implementationTO);
                 implementationTO = implementationService.read(
-                    implementationTO.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
+                        implementationTO.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
                 assertNotNull(implementationTO);
             }
         }
         assertNotNull(implementationTO);
 
         AuthenticationPolicyTO policy = new AuthenticationPolicyTO();
-        policy.setDescription("Test AuthN policy");
+        policy.setDescription("Test Authentication policy");
         policy.setKey(implementationTO.getKey());
+
+        return policy;
+    }
+
+    private static AccessPolicyTO buildAccessPolicyTO() {
+        final String accessPolicyName = "TestAccessPolicy" + getUUIDString();
+
+        ImplementationTO implementationTO = null;
+        try {
+            implementationTO = implementationService.read(
+                    AMImplementationType.ACCESS_POLICY_CONFIGURATIONS, accessPolicyName);
+        } catch (SyncopeClientException e) {
+            if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) {
+                implementationTO = new ImplementationTO();
+                implementationTO.setKey(accessPolicyName);
+                implementationTO.setEngine(ImplementationEngine.JAVA);
+                implementationTO.setType(AMImplementationType.ACCESS_POLICY_CONFIGURATIONS);
+
+                DefaultAccessPolicyConf conf = new DefaultAccessPolicyConf();
+                conf.setEnabled(true);
+                conf.setName("TestAccessPolicyConf");
+                conf.getRequiredAttributes().put("cn", List.of("admin", "Admin", "TheAdmin"));
+                implementationTO.setBody(POJOHelper.serialize(conf));
+
+                Response response = implementationService.create(implementationTO);
+                implementationTO = implementationService.read(
+                        implementationTO.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
+                assertNotNull(implementationTO);
+            }
+        }
+        assertNotNull(implementationTO);
+
+        AccessPolicyTO policy = new AccessPolicyTO();
+        policy.setDescription("Test Access policy");
+        policy.setKey(implementationTO.getKey());
+
         return policy;
     }
 
@@ -176,10 +217,25 @@ public class PolicyITCase extends AbstractITCase {
     }
 
     @Test
-    public void create() throws IOException {
-        AuthenticationPolicyTO authenticationPolicyTO = createPolicy(PolicyType.AUTHENTICATION, buildAuthenticationPolicyTO());
-        assertNotNull(authenticationPolicyTO);
+    public void getAuthenticationPolicy() {
+        AuthenticationPolicyTO policyTO =
+                policyService.read(PolicyType.AUTHENTICATION, "659b9906-4b6e-4bc0-aca0-6809dff346d4");
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByRealms().isEmpty());
+    }
 
+    @Test
+    public void getAccessPolicy() {
+        AccessPolicyTO policyTO =
+                policyService.read(PolicyType.ACCESS, "419935c7-deb3-40b3-8a9a-683037e523a2");
+
+        assertNotNull(policyTO);
+        assertTrue(policyTO.getUsedByRealms().isEmpty());
+    }
+
+    @Test
+    public void create() throws IOException {
         PullPolicyTO pullPolicyTO = createPolicy(PolicyType.PULL, buildPullPolicyTO());
         assertNotNull(pullPolicyTO);
         assertEquals("TestPullRule", pullPolicyTO.getCorrelationRules().get(AnyTypeKind.USER.name()));
@@ -188,14 +244,19 @@ public class PolicyITCase extends AbstractITCase {
         assertNotNull(pushPolicyTO);
         assertEquals("TestPushRule", pushPolicyTO.getCorrelationRules().get(AnyTypeKind.USER.name()));
 
+        AuthenticationPolicyTO authenticationPolicyTO = createPolicy(PolicyType.AUTHENTICATION,
+                buildAuthenticationPolicyTO());
+        assertNotNull(authenticationPolicyTO);
+        assertEquals("Test Authentication policy", authenticationPolicyTO.getDescription());
 
-//        AccessPolicyTO accessPolicyTO = createPolicy(PolicyType.ACCESS, buildAccessPolicyTO());
-//        assertNotNull(authenticationPolicyTO);
+        AccessPolicyTO accessPolicyTO = createPolicy(PolicyType.ACCESS, buildAccessPolicyTO());
+        assertNotNull(accessPolicyTO);
+        assertEquals("Test Access policy", accessPolicyTO.getDescription());
     }
 
-
     @Test
     public void update() {
+        // 1. Password policy
         PasswordPolicyTO globalPolicy = policyService.read(PolicyType.PASSWORD, "ce93fcda-dc3a-4369-a7b0-a6108c261c85");
 
         PasswordPolicyTO policy = SerializationUtils.clone(globalPolicy);
@@ -222,6 +283,78 @@ public class PolicyITCase extends AbstractITCase {
         ruleConf = POJOHelper.deserialize(rule.getBody(), DefaultPasswordRuleConf.class);
         assertEquals(22, ruleConf.getMaxLength());
         assertEquals(8, ruleConf.getMinLength());
+
+        // 2. Authentication policy
+        AuthenticationPolicyTO globalAuthPolicyTO =
+                policyService.read(PolicyType.AUTHENTICATION, "659b9906-4b6e-4bc0-aca0-6809dff346d4");
+
+        AuthenticationPolicyTO newAuthPolicyTO = SerializationUtils.clone(globalAuthPolicyTO);
+        newAuthPolicyTO.setKey("NewAuthPolicyConf");
+        newAuthPolicyTO.setDescription("Another simple authentication policy");
+
+        // create a new authentication policy using the former as a template
+        newAuthPolicyTO = createPolicy(PolicyType.AUTHENTICATION, newAuthPolicyTO);
+        assertNotNull(newAuthPolicyTO);
+        assertNotEquals(globalAuthPolicyTO.getKey(), newAuthPolicyTO.getKey());
+
+        ImplementationTO authPolicyImplementationTO = implementationService.read(
+                AMImplementationType.AUTH_POLICY_CONFIGURATIONS, "MyDefaultAuthenticationPolicyConf");
+        assertNotNull(authPolicyImplementationTO);
+        assertFalse(StringUtils.isBlank(authPolicyImplementationTO.getBody()));
+
+        DefaultAuthenticationPolicyConf authPolicyConf =
+                POJOHelper.deserialize(authPolicyImplementationTO.getBody(), DefaultAuthenticationPolicyConf.class);
+        assertNotNull(authPolicyConf);
+        authPolicyConf.getAuthenticationModules().add("LdapAuthentication");
+        authPolicyImplementationTO.setBody(POJOHelper.serialize(authPolicyConf));
+
+        // update new authentication policy
+        policyService.update(PolicyType.AUTHENTICATION, newAuthPolicyTO);
+        newAuthPolicyTO = policyService.read(PolicyType.AUTHENTICATION, newAuthPolicyTO.getKey());
+        assertNotNull(newAuthPolicyTO);
+
+        authPolicyConf =
+                POJOHelper.deserialize(authPolicyImplementationTO.getBody(), DefaultAuthenticationPolicyConf.class);
+        assertNotNull(authPolicyConf);
+        assertEquals(2, authPolicyConf.getAuthenticationModules().size());
+        assertTrue(authPolicyConf.getAuthenticationModules().contains("LdapAuthentication"));
+
+        // 3. Access policy
+        AccessPolicyTO globalAccessPolicyTO =
+                policyService.read(PolicyType.ACCESS, "419935c7-deb3-40b3-8a9a-683037e523a2");
+
+        AccessPolicyTO newAccessPolicyTO = SerializationUtils.clone(globalAccessPolicyTO);
+        newAccessPolicyTO.setKey("NewAccessPolicyConf");
+        newAccessPolicyTO.setDescription("Another simple access policy");
+
+        // create a new access policy using the former as a template
+        newAccessPolicyTO = createPolicy(PolicyType.ACCESS, newAccessPolicyTO);
+        assertNotNull(newAccessPolicyTO);
+        assertNotEquals(globalAccessPolicyTO.getKey(), newAccessPolicyTO.getKey());
+
+        ImplementationTO accessPolicyImplementationTO = implementationService.read(
+                AMImplementationType.ACCESS_POLICY_CONFIGURATIONS, "MyDefaultAccessPolicyConf");
+        assertNotNull(accessPolicyImplementationTO);
+        assertFalse(StringUtils.isBlank(accessPolicyImplementationTO.getBody()));
+
+        DefaultAccessPolicyConf accessPolicyConf =
+                POJOHelper.deserialize(accessPolicyImplementationTO.getBody(), DefaultAccessPolicyConf.class);
+        assertNotNull(accessPolicyConf);
+        accessPolicyConf.getRequiredAttributes().put("ou", List.of("test"));
+        accessPolicyConf.getRequiredAttributes().put("cn", List.of("admin", "Admin"));
+        accessPolicyImplementationTO.setBody(POJOHelper.serialize(accessPolicyConf));
+
+        // update new authentication policy
+        policyService.update(PolicyType.ACCESS, newAccessPolicyTO);
+        newAccessPolicyTO = policyService.read(PolicyType.ACCESS, newAccessPolicyTO.getKey());
+        assertNotNull(newAccessPolicyTO);
+
+        accessPolicyConf =
+                POJOHelper.deserialize(accessPolicyImplementationTO.getBody(), DefaultAccessPolicyConf.class);
+        assertEquals(2, accessPolicyConf.getRequiredAttributes().size());
+        assertNotNull(accessPolicyConf.getRequiredAttributes().get("cn"));
+        assertNotNull(accessPolicyConf.getRequiredAttributes().get("ou"));
+
     }
 
     @Test
@@ -239,6 +372,34 @@ public class PolicyITCase extends AbstractITCase {
         } catch (SyncopeClientException e) {
             assertNotNull(e);
         }
+
+        AuthenticationPolicyTO authPolicy = buildAuthenticationPolicyTO();
+
+        AuthenticationPolicyTO authPolicyTO = createPolicy(PolicyType.AUTHENTICATION, authPolicy);
+        assertNotNull(authPolicyTO);
+
+        policyService.delete(PolicyType.AUTHENTICATION, authPolicyTO.getKey());
+
+        try {
+            policyService.read(PolicyType.AUTHENTICATION, authPolicyTO.getKey());
+            fail("This should not happen");
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+
+        AccessPolicyTO accessPolicy = buildAccessPolicyTO();
+
+        AccessPolicyTO accessPolicyTO = createPolicy(PolicyType.ACCESS, accessPolicy);
+        assertNotNull(accessPolicyTO);
+
+        policyService.delete(PolicyType.ACCESS, accessPolicyTO.getKey());
+
+        try {
+            policyService.read(PolicyType.ACCESS, accessPolicyTO.getKey());
+            fail("This should not happen");
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
     }
 
     @Test