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

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

commit d72f7efb68f714e665d273605d900e166133ff92
Author: Marco Di Sabatino Di Diodoro <[email protected]>
AuthorDate: Mon Jun 10 15:30:16 2019 +0200

    [SYNCOPE-163] Started to implement the persistence layer for AM
---
 .../syncope/common/lib/types/AMEntitlement.java    |  10 ++
 .../common/lib/types/AMImplementationType.java     |  36 +++++
 .../common/lib/types/AuthModuleConfPropSchema.java | 157 ++++++++++++++++++
 .../common/lib/types/AuthModuleConfProperty.java   | 100 ++++++++++++
 .../common/lib/types/AuthenticationPolicyType.java |  31 ++++
 .../AbstractAuthenticationModuleConf.java          |  63 ++++++++
 .../AbstractAuthenticationPolicyConf.java          |  53 +++++++
 .../authentication/AuthenticationModuleConf.java   |  40 +++++
 .../authentication/AuthenticationPolicyConf.java   |  33 ++++
 .../ChainAuthenticationPolicyConf.java             |  30 ++++
 .../DefaultAuthenticationModuleConf.java           |  31 ++++
 .../DefaultAuthenticationPolicyConf.java           |  59 +++++++
 .../FlowableAuthenticationPolicyConf.java          |  30 ++++
 .../common/lib/types/IdRepoImplementationType.java |   2 +-
 .../api/dao/AuthenticationChainDAO.java            |  39 +++++
 .../api/dao/AuthenticationModuleDAO.java           |  39 +++++
 .../api/dao/AuthenticationModuleRule.java          |  33 ++++
 .../api/dao/AuthenticationModuleRuleConfClass.java |  32 ++++
 .../api/dao/AuthenticationPolicyRule.java          |  33 ++++
 .../api/dao/AuthenticationPolicyRuleConfClass.java |  32 ++++
 .../api/dao/AuthenticationPostProcessorRule.java   |  23 +++
 .../AuthenticationPostProcessorRuleConfClass.java  |  23 +++
 .../api/dao/AuthenticationPreProcessorRule.java    |  30 ++++
 .../AuthenticationPreProcessorRuleConfClass.java   |  23 +++
 .../api/dao/AuthenticationProcessorDAO.java        |  35 ++++
 .../core/persistence/api/dao/PolicyDAO.java        |   3 +
 .../syncope/core/persistence/api/entity/Realm.java |   5 +
 .../entity/authentication/AuthenticationChain.java |  39 +++++
 .../authentication/AuthenticationModule.java       |  40 +++++
 .../AuthenticationPostProcessor.java               |  37 +++++
 .../authentication/AuthenticationPreProcessor.java |  30 ++++
 .../authentication/AuthenticationProcessor.java    |  34 ++++
 .../api/entity/policy/AccessPolicy.java            |  25 +++
 .../api/entity/policy/AuthenticationPolicy.java    |  63 ++++++++
 .../jpa/dao/JPAAuthenticationChainDAO.java         |  76 +++++++++
 .../jpa/dao/JPAAuthenticationModuleDAO.java        |  76 +++++++++
 .../jpa/dao/JPAAuthenticationProcessorDAO.java     |  82 ++++++++++
 .../core/persistence/jpa/dao/JPAPolicyDAO.java     |  40 +++--
 .../core/persistence/jpa/dao/JPARealmDAO.java      |  11 +-
 .../persistence/jpa/entity/JPAEntityFactory.java   |  24 +++
 .../core/persistence/jpa/entity/JPARealm.java      |  21 ++-
 .../AbstractAuthenticationProcessor.java           |  62 ++++++++
 .../authentication/JPAAuthenticationChain.java     |  90 +++++++++++
 .../authentication/JPAAuthenticationModule.java    |  97 ++++++++++++
 .../JPAAuthenticationPostProcessor.java            |  91 +++++++++++
 .../JPAAuthenticationPreProcessor.java             |  64 ++++++++
 .../jpa/entity/policy/JPAAccessPolicy.java         |  33 ++++
 .../jpa/entity/policy/JPAAuthenticationPolicy.java | 176 +++++++++++++++++++++
 .../jpa/inner/AuthenticationChainTest.java         | 104 ++++++++++++
 .../jpa/inner/AuthenticationModuleTest.java        | 106 +++++++++++++
 .../jpa/inner/AuthenticationProcessorTest.java     | 130 +++++++++++++++
 .../persistence/jpa/inner/ImplementationTest.java  |  15 +-
 .../core/persistence/jpa/inner/PolicyTest.java     |  67 ++++++++
 .../src/test/resources/domains/MasterContent.xml   |  31 +++-
 54 files changed, 2673 insertions(+), 16 deletions(-)

diff --git 
a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
index 06d511c..a1ca20a 100644
--- 
a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
+++ 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
@@ -34,6 +34,16 @@ public final class AMEntitlement {
 
     public static final String GATEWAY_ROUTE_PUSH = "GATEWAY_ROUTE_PUSH";
 
+    public static final String AUTHENTICATION_MODULE_READ = 
"AUTHENTICATION_MODULE_READ";
+
+    public static final String AUTHENTICATION_MODULE_LIST = 
"AUTHENTICATION_MODULE_LIST";
+
+    public static final String AUTHENTICATION_MODULE_CREATE = 
"AUTHENTICATION_MODULE_CREATE";
+
+    public static final String AUTHENTICATION_MODULE_UPDATE = 
"AUTHENTICATION_MODULE_UPDATE";
+
+    public static final String AUTHENTICATION_MODULE_DELETE = 
"AUTHENTICATION_MODULE_DELETE";
+
     private static final Set<String> VALUES;
 
     static {
diff --git 
a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java
 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java
new file mode 100644
index 0000000..d54bc1b
--- /dev/null
+++ 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMImplementationType.java
@@ -0,0 +1,36 @@
+/*
+ * 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.common.lib.types;
+
+public final class AMImplementationType {
+
+    public static final String AUTH_CHAIN_RULES = "AUTH_CHAIN_RULES";
+
+    public static final String AUTH_POST_PROCESSING = "AUTH_POST_PROCESSING";
+
+    public static final String AUTH_PRE_PROCESSING = "AUTH_PRE_PROCESSING";
+
+    public static final String AUTH_MODULE_CONFIGURATIONS = 
"AUTH_MODULE_CONFIGURATIONS";
+
+    public static final String AUTH_POLICY_CONFIGURATIONS = 
"AUTH_POLICY_CONFIGURATIONS";
+
+    private AMImplementationType() {
+        // private constructor for static utility class
+    }
+}
diff --git 
a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfPropSchema.java
 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfPropSchema.java
new file mode 100644
index 0000000..6ff8800
--- /dev/null
+++ 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfPropSchema.java
@@ -0,0 +1,157 @@
+/*
+ * 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.common.lib.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@XmlRootElement
+@XmlType
+public class AuthModuleConfPropSchema implements Serializable, 
Comparable<AuthModuleConfPropSchema> {
+
+    private static final long serialVersionUID = -1615574676038299363L;
+
+    private String name;
+
+    private String displayName;
+
+    private String helpMessage;
+
+    private String type = String.class.getName();
+
+    private boolean required;
+
+    private int order;
+
+    private boolean confidential;
+
+    private final List<Object> defaultValues = new ArrayList<>();
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public boolean isRequired() {
+        return required;
+    }
+
+    public void setRequired(final boolean required) {
+        this.required = required;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(final String type) {
+        this.type = type;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(final String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getHelpMessage() {
+        return helpMessage;
+    }
+
+    public void setHelpMessage(final String helpMessage) {
+        this.helpMessage = helpMessage;
+    }
+
+    public int getOrder() {
+        return order;
+    }
+
+    public void setOrder(final int order) {
+        this.order = order;
+    }
+
+    public boolean isConfidential() {
+        return confidential;
+    }
+
+    public void setConfidential(final boolean confidential) {
+        this.confidential = confidential;
+    }
+
+    @XmlElementWrapper(name = "defaultValues")
+    @XmlElement(name = "defaultValue")
+    @JsonProperty("defaultValues")
+    public List<Object> getDefaultValues() {
+        return defaultValues;
+    }
+
+    @Override
+    public int compareTo(final AuthModuleConfPropSchema other) {
+        return this.getOrder() > other.getOrder()
+                ? 1
+                : this.getOrder() < other.getOrder()
+                ? -1
+                : 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(name).
+                append(type).
+                append(required).
+                append(order).
+                append(confidential).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AuthModuleConfPropSchema other = (AuthModuleConfPropSchema) obj;
+        return new EqualsBuilder().
+                append(name, other.name).
+                append(type, other.type).
+                append(required, other.required).
+                append(order, other.order).
+                append(confidential, other.confidential).
+                build();
+    }
+}
diff --git 
a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfProperty.java
 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfProperty.java
new file mode 100644
index 0000000..d3a125f
--- /dev/null
+++ 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthModuleConfProperty.java
@@ -0,0 +1,100 @@
+/*
+ * 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.common.lib.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@XmlRootElement
+@XmlType
+public class AuthModuleConfProperty implements Serializable, 
Comparable<AuthModuleConfProperty> {
+
+    private static final long serialVersionUID = 7291446596155549328L;
+
+    private AuthModuleConfPropSchema schema;
+
+    private final List<Object> values = new ArrayList<>();
+
+    private boolean overridable;
+
+    public AuthModuleConfPropSchema getSchema() {
+        return schema;
+    }
+
+    public void setSchema(final AuthModuleConfPropSchema schema) {
+        this.schema = schema;
+    }
+
+    @XmlElementWrapper(name = "values")
+    @XmlElement(name = "value")
+    @JsonProperty("values")
+    public List<Object> getValues() {
+        return values;
+    }
+
+    public boolean isOverridable() {
+        return overridable;
+    }
+
+    public void setOverridable(final boolean overridable) {
+        this.overridable = overridable;
+    }
+
+    @Override
+    public int compareTo(final AuthModuleConfProperty connConfProperty) {
+        return ObjectUtils.compare(this.getSchema(), 
connConfProperty.getSchema());
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(schema).
+                append(values).
+                append(overridable).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AuthModuleConfProperty other = (AuthModuleConfProperty) obj;
+        return new EqualsBuilder().
+                append(schema, other.schema).
+                append(values, other.values).
+                append(overridable, other.overridable).
+                build();
+    }
+}
diff --git 
a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthenticationPolicyType.java
 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthenticationPolicyType.java
new file mode 100644
index 0000000..b2bab89
--- /dev/null
+++ 
b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AuthenticationPolicyType.java
@@ -0,0 +1,31 @@
+/*
+ * 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.common.lib.types;
+
+
+public final class AuthenticationPolicyType {
+    
+    public static final String AUTHENTICATION_POLICY_BPM = 
"AUTHENTICATION_POLICY_BPM";
+    
+    public static final String AUTHENTICATION_POLICY_CHAIN = 
"AUTHENTICATION_POLICY_CHAIN";
+
+    private AuthenticationPolicyType() {
+        // private constructor for static utility class
+    }
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationModuleConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationModuleConf.java
new file mode 100644
index 0000000..c8b8e5c
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationModuleConf.java
@@ -0,0 +1,63 @@
+/*
+ * 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.common.lib.authentication;
+
+import java.io.Serializable;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.StringUtils;
+
+@XmlType
+@XmlSeeAlso({ DefaultAuthenticationModuleConf.class })
+public abstract class AbstractAuthenticationModuleConf implements 
Serializable, AuthenticationModuleConf {
+
+    private static final long serialVersionUID = 4153200197344709778L;
+
+    private String name;
+    
+    private int authenticationLevel;
+
+    public AbstractAuthenticationModuleConf() {
+        this(StringUtils.EMPTY);
+        setName(getClass().getName());
+    }
+
+    public AbstractAuthenticationModuleConf(final String name) {
+        super();
+        this.name = name;
+    }
+
+    @Override
+    public final String getName() {
+        return name;
+    }
+
+    public final void setName(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public int getAuthenticationLevel() {
+        return authenticationLevel;
+    }
+
+    public void setAuthenticationLevel(final int authenticationLevel) {
+        this.authenticationLevel = authenticationLevel;
+    }
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java
new file mode 100644
index 0000000..9db030d
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AbstractAuthenticationPolicyConf.java
@@ -0,0 +1,53 @@
+/*
+ * 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.common.lib.authentication;
+
+import java.io.Serializable;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.StringUtils;
+
+@XmlType
+@XmlSeeAlso({ DefaultAuthenticationPolicyConf.class, 
ChainAuthenticationPolicyConf.class,
+    FlowableAuthenticationPolicyConf.class })
+public abstract class AbstractAuthenticationPolicyConf implements 
Serializable, AuthenticationPolicyConf {
+
+    private static final long serialVersionUID = 9185127128182430142L;
+
+    private String name;
+
+    public AbstractAuthenticationPolicyConf() {
+        this(StringUtils.EMPTY);
+        setName(getClass().getName());
+    }
+
+    public AbstractAuthenticationPolicyConf(final String name) {
+        super();
+        this.name = name;
+    }
+
+    @Override
+    public final String getName() {
+        return name;
+    }
+
+    public final void setName(final String name) {
+        this.name = name;
+    }
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java
new file mode 100644
index 0000000..71348e1
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationModuleConf.java
@@ -0,0 +1,40 @@
+/*
+ * 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.common.lib.authentication;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import java.io.Serializable;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, 
property = "@class")
+public interface AuthenticationModuleConf extends Serializable {
+
+    /**
+     * Give name of related authentication module instance.
+     *
+     * @return name of this authentication module instance
+     */
+    String getName();
+
+    /**
+     * Give authentication level of related authentication module instance.
+     *
+     * @return authentication level of this authentication module instance
+     */
+    int getAuthenticationLevel();
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java
new file mode 100644
index 0000000..d8d3e4b
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/AuthenticationPolicyConf.java
@@ -0,0 +1,33 @@
+/*
+ * 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.common.lib.authentication;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import java.io.Serializable;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, 
property = "@class")
+public interface AuthenticationPolicyConf extends Serializable {
+
+    /**
+     * Give name of related authentication policy instance.
+     *
+     * @return name of this authentication policy instance
+     */
+    String getName();
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/ChainAuthenticationPolicyConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/ChainAuthenticationPolicyConf.java
new file mode 100644
index 0000000..171f892
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/ChainAuthenticationPolicyConf.java
@@ -0,0 +1,30 @@
+/*
+ * 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.common.lib.authentication;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "chainAuthenticationPolicyConf")
+@XmlType
+public class ChainAuthenticationPolicyConf extends 
AbstractAuthenticationPolicyConf {
+
+    private static final long serialVersionUID = -984521961849586727L;
+
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationModuleConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationModuleConf.java
new file mode 100644
index 0000000..132a64b
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationModuleConf.java
@@ -0,0 +1,31 @@
+/*
+ * 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.common.lib.authentication;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "defaultAuthenticationModuleConf")
+@XmlType
+public class DefaultAuthenticationModuleConf extends 
AbstractAuthenticationModuleConf {
+
+    private static final long serialVersionUID = -7775771400318503131L;
+    
+    
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java
new file mode 100644
index 0000000..f4e4d3d
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/DefaultAuthenticationPolicyConf.java
@@ -0,0 +1,59 @@
+/*
+ * 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.common.lib.authentication;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "defaultAuthenticationPolicyConf")
+@XmlType
+public class DefaultAuthenticationPolicyConf extends 
AbstractAuthenticationPolicyConf {
+
+    private static final long serialVersionUID = 6021204813821798285L;
+
+    /**
+     * Authentication attribute.
+     */
+    private final List<String> authenticationAttributes = new ArrayList<>();
+
+    /**
+     * Case sensitive.
+     */
+    private boolean caseSensitiveAuthentication;
+
+    public boolean isCaseSensitiveAuthentication() {
+        return caseSensitiveAuthentication;
+    }
+
+    public void setCaseSensitiveAuthentication(final boolean 
caseSensitiveAuthentication) {
+        this.caseSensitiveAuthentication = caseSensitiveAuthentication;
+    }
+
+    @XmlElementWrapper(name = "authenticationAttributes")
+    @XmlElement(name = "attribute")
+    @JsonProperty("authenticationAttributes")
+    public List<String> getAuthenticationAttributes() {
+        return authenticationAttributes;
+    }
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/FlowableAuthenticationPolicyConf.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/FlowableAuthenticationPolicyConf.java
new file mode 100644
index 0000000..db7a14a
--- /dev/null
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/authentication/FlowableAuthenticationPolicyConf.java
@@ -0,0 +1,30 @@
+/*
+ * 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.common.lib.authentication;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "flowableAuthenticationPolicyConf")
+@XmlType
+public class FlowableAuthenticationPolicyConf extends 
AbstractAuthenticationPolicyConf {
+
+    private static final long serialVersionUID = -984521961849586727L;
+
+}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
index 013cb06..037bffa 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoImplementationType.java
@@ -40,7 +40,7 @@ public final class IdRepoImplementationType {
     public static final String RECIPIENTS_PROVIDER = "RECIPIENTS_PROVIDER";
 
     public static final String AUDIT_APPENDER = "AUDIT_APPENDER";
-
+    
     private static final Map<String, String> VALUES = Map.ofEntries(
             Pair.of(JWT_SSO_PROVIDER, 
"org.apache.syncope.core.spring.security.JWTSSOProvider"),
             Pair.of(REPORTLET, 
"org.apache.syncope.core.persistence.api.dao.Reportlet"),
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationChainDAO.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationChainDAO.java
new file mode 100644
index 0000000..a349844
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationChainDAO.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationChain;
+
+public interface AuthenticationChainDAO extends DAO<AuthenticationChain> {
+
+    AuthenticationChain find(String key);
+
+    List<AuthenticationChain> findByRule(Implementation configuration);
+
+    List<AuthenticationChain> findAll();
+
+    AuthenticationChain save(AuthenticationChain authenticationChain);
+
+    void delete(String key);
+
+    void delete(AuthenticationChain authenticationChain);
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleDAO.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleDAO.java
new file mode 100644
index 0000000..4d48214
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleDAO.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationModule;
+
+public interface AuthenticationModuleDAO extends DAO<AuthenticationModule> {
+
+    AuthenticationModule find(String key);
+
+    List<AuthenticationModule> findByConfiguration(Implementation 
configuration);
+
+    List<AuthenticationModule> findAll();
+
+    AuthenticationModule save(AuthenticationModule authenticationModule);
+
+    void delete(String key);
+
+    void delete(AuthenticationModule authenticationModule);
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleRule.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleRule.java
new file mode 100644
index 0000000..ca89010
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleRule.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import org.apache.syncope.common.lib.authentication.AuthenticationPolicyConf;
+
+/**
+ * Interface for authentication module rule to be evaluated during 
authentication.
+ */
+public interface AuthenticationModuleRule {
+
+    default void setConf(AuthenticationPolicyConf conf) {
+    }
+    
+    void authenticate();
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleRuleConfClass.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleRuleConfClass.java
new file mode 100644
index 0000000..f920a9b
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationModuleRuleConfClass.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.syncope.common.lib.authentication.AuthenticationModuleConf;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AuthenticationModuleRuleConfClass {
+
+    Class<? extends AuthenticationModuleConf> value();
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPolicyRule.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPolicyRule.java
new file mode 100644
index 0000000..27bd7f6
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPolicyRule.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import org.apache.syncope.common.lib.authentication.AuthenticationPolicyConf;
+
+/**
+ * Interface for authentication policy rule to be evaluated during 
authentication.
+ */
+public interface AuthenticationPolicyRule {
+
+    default void setConf(AuthenticationPolicyConf conf) {
+    }
+
+    void authenticate();
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPolicyRuleConfClass.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPolicyRuleConfClass.java
new file mode 100644
index 0000000..a4bc2d3
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPolicyRuleConfClass.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.syncope.common.lib.authentication.AuthenticationPolicyConf;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AuthenticationPolicyRuleConfClass {
+
+    Class<? extends AuthenticationPolicyConf> value();
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPostProcessorRule.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPostProcessorRule.java
new file mode 100644
index 0000000..883a80d
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPostProcessorRule.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+public class AuthenticationPostProcessorRule {
+    
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPostProcessorRuleConfClass.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPostProcessorRuleConfClass.java
new file mode 100644
index 0000000..b002d30
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPostProcessorRuleConfClass.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+public class AuthenticationPostProcessorRuleConfClass {
+    
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPreProcessorRule.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPreProcessorRule.java
new file mode 100644
index 0000000..b097541
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPreProcessorRule.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AuthenticationPreProcessorRule {
+    
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPreProcessorRuleConfClass.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPreProcessorRuleConfClass.java
new file mode 100644
index 0000000..040054c
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationPreProcessorRuleConfClass.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+public class AuthenticationPreProcessorRuleConfClass {
+    
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationProcessorDAO.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationProcessorDAO.java
new file mode 100644
index 0000000..92e40b9
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuthenticationProcessorDAO.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationProcessor;
+
+public interface AuthenticationProcessorDAO extends 
DAO<AuthenticationProcessor> {
+
+    <T extends AuthenticationProcessor> T find(String key);
+
+    <T extends AuthenticationProcessor> List<T> find(Class<T> reference);
+
+    List<AuthenticationProcessor> findAll();
+
+    <T extends AuthenticationProcessor> T save(T authenticationProcessor);
+
+    <T extends AuthenticationProcessor> void delete(T authenticationProcessor);
+}
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..8cedd32 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
@@ -21,6 +21,7 @@ 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.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;
@@ -40,6 +41,8 @@ public interface PolicyDAO extends DAO<Policy> {
     List<PullPolicy> findByPullCorrelationRule(Implementation correlationRule);
 
     List<PushPolicy> findByPushCorrelationRule(Implementation correlationRule);
+    
+    List<AuthenticationPolicy> findByAuthenticationPolicy(Implementation 
authenticationPolicy);
 
     List<AccountPolicy> findByResource(ExternalResource resource);
 
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 c4ef281..19c4e6c 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,6 +21,7 @@ package org.apache.syncope.core.persistence.api.entity;
 import java.util.List;
 import java.util.Optional;
 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.resource.ExternalResource;
 
@@ -35,6 +36,8 @@ public interface Realm extends Entity {
     AccountPolicy getAccountPolicy();
 
     PasswordPolicy getPasswordPolicy();
+    
+    AuthenticationPolicy getAuthenticationPolicy();
 
     void setName(String name);
 
@@ -43,6 +46,8 @@ public interface Realm extends Entity {
     void setAccountPolicy(AccountPolicy accountPolicy);
 
     void setPasswordPolicy(PasswordPolicy passwordPolicy);
+    
+    void setAuthenticationPolicy(AuthenticationPolicy authenticationPolicy);
 
     boolean add(Implementation action);
 
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationChain.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationChain.java
new file mode 100644
index 0000000..e2c5b2a
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationChain.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.authentication;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+
+public interface AuthenticationChain extends Entity {
+
+    String getName();
+
+    void setName(String name);
+
+    String getDescription();
+
+    void setDescription(String description);
+
+    boolean add(Implementation configuration);
+
+    List<? extends Implementation> getConfigurations();
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationModule.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationModule.java
new file mode 100644
index 0000000..d1bf6b3
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationModule.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.authentication;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+
+public interface AuthenticationModule extends Entity {
+
+    void setName(String displayName);
+
+    String getName();
+
+    List<? extends Implementation> getConfigurations();
+    
+    boolean add(Implementation configuration);
+    
+    TraceLevel getTraceLevel();
+
+    void setTraceLevel(TraceLevel createTraceLevel);
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationPostProcessor.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationPostProcessor.java
new file mode 100644
index 0000000..09e74cb
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationPostProcessor.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.authentication;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+
+public interface AuthenticationPostProcessor extends AuthenticationProcessor {
+
+    String getDefaultSuccessLoginURL();
+
+    String getDefaultFailureLoginURL();
+
+    List<? extends Implementation> getAuthenticationPostProcessing();
+
+    void setDefaultSuccessLoginURL(String defaultSuccessLoginURL);
+
+    void setDefaultFailureLoginURL(String defaultFailureLoginURL);
+
+    boolean addAuthPostProcessing(Implementation authPostProcessing);
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationPreProcessor.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationPreProcessor.java
new file mode 100644
index 0000000..aa41d65
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationPreProcessor.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.authentication;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+
+public interface AuthenticationPreProcessor extends AuthenticationProcessor {
+
+    List<? extends Implementation> getAuthenticationPreProcessing();
+    
+    boolean addAuthPreProcessing(Implementation authPreProcessing);
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationProcessor.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationProcessor.java
new file mode 100644
index 0000000..197fd30
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/authentication/AuthenticationProcessor.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.authentication;
+
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import 
org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
+
+public interface AuthenticationProcessor extends Entity {
+
+    AuthenticationPolicy getAuthenticationPolicy();
+
+    String getName();
+
+    void setAuthenticationPolicy(AuthenticationPolicy authenticationPolicy);
+
+    void setName(String name);
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccessPolicy.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccessPolicy.java
new file mode 100644
index 0000000..2cb30d6
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccessPolicy.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.policy;
+
+public interface AccessPolicy extends Policy {
+
+
+
+}
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AuthenticationPolicy.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AuthenticationPolicy.java
new file mode 100644
index 0000000..20df9a6
--- /dev/null
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AuthenticationPolicy.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.policy;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+
+public interface AuthenticationPolicy extends Policy {
+
+    String getName();
+
+    List<? extends Implementation> getConfigurations();
+
+    int getMaxAuthenticationAttempts();
+
+    int getAuthenticationAttemptsInterval();
+
+    int getAuthenticationFailureLockoutDuration();
+
+    String getLockoutAttributeName();
+
+    String getLockoutAttributeValue();
+
+    AuthenticationPostProcessor getAuthenticationPostProcessor();
+
+    AuthenticationPreProcessor getAuthenticationPreProcessor();
+
+    void setName(String name);
+
+    boolean addConfiguration(Implementation configuration);
+
+    void setMaxAuthenticationAttempts(int maxAuthenticationAttempts);
+
+    void setAuthenticationAttemptsInterval(int authenticationAttemptsInterval);
+
+    void setAuthenticationFailureLockoutDuration(int 
authenticationFailureLockoutDuration);
+
+    void setLockoutAttributeName(String lockoutAttributeName);
+
+    void setLockoutAttributeValue(String lockoutAttributeValue);
+
+    void setAuthenticationPostProcessor(AuthenticationPostProcessor 
authenticationPostProcessor);
+
+    void setAuthenticationPreProcessor(AuthenticationPreProcessor 
authenticationPreProcessor);
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationChainDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationChainDAO.java
new file mode 100644
index 0000000..f50c1a5
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationChainDAO.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationChainDAO;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationChain;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationChain;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAAuthenticationChainDAO extends 
AbstractDAO<AuthenticationChain> implements AuthenticationChainDAO {
+
+    @Override
+    public AuthenticationChain find(final String key) {
+        return entityManager().find(JPAAuthenticationChain.class, key);
+    }
+
+    @Override
+    public List<AuthenticationChain> findByRule(final Implementation 
configuration) {
+        TypedQuery<AuthenticationChain> query = entityManager().createQuery(
+                "SELECT e FROM " + 
JPAAuthenticationChain.class.getSimpleName() + " e "
+                + "WHERE :rule MEMBER OF e.rules", AuthenticationChain.class);
+        query.setParameter("rule", configuration);
+        return query.getResultList();
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public List<AuthenticationChain> findAll() {
+        TypedQuery<AuthenticationChain> query = entityManager().createQuery(
+                "SELECT e FROM " + 
JPAAuthenticationChain.class.getSimpleName() + " e", AuthenticationChain.class);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public AuthenticationChain save(final AuthenticationChain 
authenticationChain) {
+        return entityManager().merge(authenticationChain);
+    }
+
+    @Override
+    public void delete(final String key) {
+        AuthenticationChain authenticationChain = find(key);
+        if (authenticationChain == null) {
+            return;
+        }
+
+        delete(authenticationChain);
+    }
+
+    @Override
+    public void delete(final AuthenticationChain authenticationChain) {
+        entityManager().remove(authenticationChain);
+    }
+
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationModuleDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationModuleDAO.java
new file mode 100644
index 0000000..99d335d
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationModuleDAO.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationModuleDAO;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationModule;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationModule;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAAuthenticationModuleDAO extends 
AbstractDAO<AuthenticationModule> implements AuthenticationModuleDAO {
+
+    @Override
+    public AuthenticationModule find(final String key) {
+        return entityManager().find(JPAAuthenticationModule.class, key);
+    }
+
+    @Override
+    public List<AuthenticationModule> findByConfiguration(final Implementation 
configuration) {
+        TypedQuery<AuthenticationModule> query = entityManager().createQuery(
+                "SELECT e FROM " + 
JPAAuthenticationModule.class.getSimpleName() + " e "
+                + "WHERE :configuration MEMBER OF e.configurations", 
AuthenticationModule.class);
+        query.setParameter("configuration", configuration);
+        return query.getResultList();
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public List<AuthenticationModule> findAll() {
+        TypedQuery<AuthenticationModule> query = entityManager().createQuery(
+                "SELECT e FROM " + 
JPAAuthenticationModule.class.getSimpleName() + " e", 
AuthenticationModule.class);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public AuthenticationModule save(final AuthenticationModule 
authenticationModule) {
+        return entityManager().merge(authenticationModule);
+    }
+
+    @Override
+    public void delete(final String key) {
+        AuthenticationModule authenticationModule = find(key);
+        if (authenticationModule == null) {
+            return;
+        }
+
+        delete(authenticationModule);
+    }
+
+    @Override
+    public void delete(final AuthenticationModule authenticationModule) {
+        entityManager().remove(authenticationModule);
+    }
+
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationProcessorDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationProcessorDAO.java
new file mode 100644
index 0000000..1ae4bac
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthenticationProcessorDAO.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationProcessorDAO;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.AbstractAuthenticationProcessor;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationPreProcessor;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAAuthenticationProcessorDAO extends 
AbstractDAO<AuthenticationProcessor> implements
+        AuthenticationProcessorDAO {
+
+    private <T extends AuthenticationProcessor> Class<? extends 
AbstractAuthenticationProcessor> getEntityReference(
+            final Class<T> reference) {
+        return AuthenticationPreProcessor.class.isAssignableFrom(reference)
+                ? JPAAuthenticationPreProcessor.class
+                : AuthenticationPostProcessor.class.isAssignableFrom(reference)
+                ? JPAAuthenticationPostProcessor.class
+                : null;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends AuthenticationProcessor> T find(final String key) {
+        return (T) entityManager().find(AbstractAuthenticationProcessor.class, 
key);
+    }
+
+    @Override
+    public <T extends AuthenticationProcessor> List<T> find(final Class<T> 
reference) {
+        TypedQuery<T> query = entityManager().createQuery(
+                "SELECT e FROM " + 
getEntityReference(reference).getSimpleName() + " e", reference);
+
+        return query.getResultList();
+    }
+
+    public List<AuthenticationProcessor> findAll() {
+        TypedQuery<AuthenticationProcessor> query = 
entityManager().createQuery(
+                "SELECT e FROM " + 
AbstractAuthenticationProcessor.class.getSimpleName()
+                + " e", AuthenticationProcessor.class);
+        return query.getResultList();
+    }
+
+    @Override
+    public <T extends AuthenticationProcessor> T save(final T 
authenticationProcessor) {
+        return entityManager().merge(authenticationProcessor);
+    }
+
+    @Override
+    public <T extends AuthenticationProcessor> void delete(final T 
authenticationProcessor) {
+        AuthenticationPolicy policy = 
authenticationProcessor.getAuthenticationPolicy();
+        if (authenticationProcessor instanceof AuthenticationPreProcessor) {
+            policy.setAuthenticationPreProcessor(null);
+        } else {
+            policy.setAuthenticationPostProcessor(null);
+        }
+        entityManager().remove(authenticationProcessor);
+    }
+}
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 c1cb136..6d23de2 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
@@ -25,6 +25,7 @@ import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 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.policy.AuthenticationPolicy;
 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.policy.Policy;
@@ -32,6 +33,7 @@ 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.jpa.entity.policy.AbstractPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
+import 
org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthenticationPolicy;
 import 
org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
@@ -61,6 +63,8 @@ public class JPAPolicyDAO extends AbstractDAO<Policy> 
implements PolicyDAO {
                 ? JPAPullPolicy.class
                 : PushPolicy.class.isAssignableFrom(reference)
                 ? JPAPushPolicy.class
+                : AuthenticationPolicy.class.isAssignableFrom(reference)
+                ? JPAAuthenticationPolicy.class
                 : null;
     }
 
@@ -119,6 +123,16 @@ public class JPAPolicyDAO extends AbstractDAO<Policy> 
implements PolicyDAO {
     }
 
     @Override
+    public List<AuthenticationPolicy> findByAuthenticationPolicy(final 
Implementation authenticationRule) {
+        TypedQuery<AuthenticationPolicy> query = entityManager().createQuery(
+                "SELECT e FROM " + 
JPAAuthenticationPolicy.class.getSimpleName() + " e "
+                + "WHERE :authenticationRule MEMBER OF e.configurations", 
AuthenticationPolicy.class);
+        query.setParameter("authenticationRule", authenticationRule);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<AccountPolicy> findByResource(final ExternalResource resource) 
{
         TypedQuery<AccountPolicy> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAccountPolicy.class.getSimpleName() + " 
e "
@@ -147,20 +161,24 @@ 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);
             }
         });
 
-        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);
-            }
-        });
+        if (!(policy instanceof AuthenticationPolicy)) {
+            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);
+                }
+            });
+        }
 
         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 d2ed275..85934f7 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.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.ProvisioningPolicy;
@@ -139,10 +140,18 @@ public class JPARealmDAO extends AbstractDAO<Realm> 
implements RealmDAO {
         if (ProvisioningPolicy.class.isAssignableFrom(policy.getClass())) {
             return Collections.<Realm>emptyList();
         }
+        String policyColumn = null;
+        if (policy instanceof AccountPolicy) {
+            policyColumn = "accountPolicy";
+        } else if (policy instanceof PasswordPolicy) {
+            policyColumn = "passwordPolicy";
+        } else if (policy instanceof AuthenticationPolicy) {
+            policyColumn = "authenticationPolicy";
+        }
 
         TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e WHERE 
e."
-                + (policy instanceof AccountPolicy ? "accountPolicy" : 
"passwordPolicy") + "=:policy", Realm.class);
+                + policyColumn + "=:policy", Realm.class);
         query.setParameter("policy", policy);
 
         List<Realm> result = new ArrayList<>();
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index ac8865a..1942a44 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -126,6 +126,12 @@ import 
org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
 import org.apache.syncope.core.persistence.api.entity.Remediation;
 import org.apache.syncope.core.persistence.api.entity.SchemaLabel;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationChain;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationModule;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+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.ExternalResourceHistoryConf;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import 
org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullCorrelationRuleEntity;
@@ -134,6 +140,12 @@ import 
org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnitItem;
 import 
org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
 import 
org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationChain;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationModule;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationPreProcessor;
+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.JPAPushCorrelationRuleEntity;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
@@ -284,6 +296,18 @@ public class JPAEntityFactory implements EntityFactory {
             result = (E) new JPABatch();
         } else if (reference.equals(GatewayRoute.class)) {
             result = (E) new JPAGatewayRoute();
+        } else if (reference.equals(AuthenticationModule.class)) {
+            result = (E) new JPAAuthenticationModule();
+        } else if (reference.equals(AuthenticationChain.class)) {
+            result = (E) new JPAAuthenticationChain();
+        } else if (reference.equals(AuthenticationPolicy.class)) {
+            result = (E) new JPAAuthenticationPolicy();
+        } else if (reference.equals(AuthenticationPostProcessor.class)) {
+            result = (E) new JPAAuthenticationPostProcessor();
+        } else if (reference.equals(AuthenticationPreProcessor.class)) {
+            result = (E) new JPAAuthenticationPreProcessor();
+        } else if (reference.equals(AccessPolicy.class)) {
+            result = (E) new JPAAccessPolicy();
         } else {
             throw new IllegalArgumentException("Could not find a JPA 
implementation of " + reference.getName());
         }
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 80cafac..b91498b 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
@@ -43,8 +43,10 @@ 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.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+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.jpa.entity.policy.JPAAccountPolicy;
+import 
org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthenticationPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
 import 
org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.RealmCheck;
@@ -72,6 +74,9 @@ public class JPARealm extends AbstractGeneratedKeyEntity 
implements Realm {
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAAccountPolicy accountPolicy;
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAuthenticationPolicy authenticationPolicy;
+
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(name = TABLE + "Action",
             joinColumns =
@@ -90,7 +95,8 @@ public class JPARealm extends AbstractGeneratedKeyEntity 
implements Realm {
             @JoinColumn(name = "realm_id"),
             inverseJoinColumns =
             @JoinColumn(name = "resource_id"),
-            uniqueConstraints = @UniqueConstraint(columnNames = { "realm_id", 
"resource_id" }))
+            uniqueConstraints =
+            @UniqueConstraint(columnNames = { "realm_id", "resource_id" }))
     private List<JPAExternalResource> resources = new ArrayList<>();
 
     @Override
@@ -121,6 +127,13 @@ public class JPARealm extends AbstractGeneratedKeyEntity 
implements Realm {
     }
 
     @Override
+    public AuthenticationPolicy getAuthenticationPolicy() {
+        return authenticationPolicy == null && getParent() != null
+                ? getParent().getAuthenticationPolicy() 
+                : authenticationPolicy;
+    }
+
+    @Override
     public void setName(final String name) {
         this.name = name;
     }
@@ -144,6 +157,12 @@ public class JPARealm extends AbstractGeneratedKeyEntity 
implements Realm {
     }
 
     @Override
+    public void setAuthenticationPolicy(final AuthenticationPolicy 
authenticationPolicy) {
+        checkType(authenticationPolicy, JPAAuthenticationPolicy.class);
+        this.authenticationPolicy = (JPAAuthenticationPolicy) 
authenticationPolicy;
+    }
+
+    @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/authentication/AbstractAuthenticationProcessor.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/AbstractAuthenticationProcessor.java
new file mode 100644
index 0000000..be02256
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/AbstractAuthenticationProcessor.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.authentication;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
+import 
org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+import 
org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthenticationPolicy;
+
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public abstract class AbstractAuthenticationProcessor extends 
AbstractGeneratedKeyEntity
+        implements AuthenticationProcessor {
+
+    private static final long serialVersionUID = -1419270763197087924L;
+
+    @Column(unique = true, nullable = false)
+    private String name;
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @OneToOne(optional = false)
+    private JPAAuthenticationPolicy authenticationPolicy;
+
+    public AuthenticationPolicy getAuthenticationPolicy() {
+        return authenticationPolicy;
+    }
+
+    public void setAuthenticationPolicy(final AuthenticationPolicy 
authenticationPolicy) {
+        checkType(authenticationPolicy, JPAAuthenticationPolicy.class);
+        this.authenticationPolicy = (JPAAuthenticationPolicy) 
authenticationPolicy;
+    }
+
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationChain.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationChain.java
new file mode 100644
index 0000000..b3fffa0
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationChain.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.authentication;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationChain;
+import 
org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+
+@Entity
+@Table(name = JPAAuthenticationChain.TABLE)
+public class JPAAuthenticationChain extends AbstractGeneratedKeyEntity 
implements AuthenticationChain {
+
+    private static final long serialVersionUID = -1169616553574108334L;
+
+    public static final String TABLE = "AuthenticationChain";
+
+    @Column(unique = true, nullable = false)
+    private String name;
+
+    @Column(unique = false, nullable = true)
+    private String description;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = TABLE + "Conf",
+            joinColumns =
+            @JoinColumn(name = "authentication_chain_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "implementation_id"))
+    private List<JPAImplementation> configurations = new ArrayList<>();
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public List<? extends Implementation> getConfigurations() {
+        return configurations;
+    }
+
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+
+    @Override
+    public boolean add(final Implementation configuration) {
+        checkType(configuration, JPAImplementation.class);
+        checkImplementationType(configuration, 
AMImplementationType.AUTH_CHAIN_RULES);
+        return configurations.contains((JPAImplementation) configuration)
+                || configurations.add((JPAImplementation) configuration);
+    }
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationModule.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationModule.java
new file mode 100644
index 0000000..b772443
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationModule.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.authentication;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationModule;
+import 
org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+
+@Entity
+@Table(name = JPAAuthenticationModule.TABLE)
+public class JPAAuthenticationModule extends AbstractGeneratedKeyEntity 
implements AuthenticationModule {
+
+    private static final long serialVersionUID = 7422422526695279794L;
+
+    public static final String TABLE = "AuthenticationModule";
+
+    @Column(unique = true, nullable = false)
+    private String name;
+
+    @Enumerated(EnumType.STRING)
+    @NotNull
+    private TraceLevel traceLevel = TraceLevel.FAILURES;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = TABLE + "Conf",
+            joinColumns =
+            @JoinColumn(name = "authentication_module_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "implementation_id"))
+    private List<JPAImplementation> configurations = new ArrayList<>();
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public TraceLevel getTraceLevel() {
+        return traceLevel;
+    }
+
+    @Override
+    public List<? extends Implementation> getConfigurations() {
+        return configurations;
+    }
+
+    @Override
+    public void setTraceLevel(final TraceLevel createTraceLevel) {
+        this.traceLevel = createTraceLevel;
+    }
+
+    @Override
+    public boolean add(final Implementation configuration) {
+        checkType(configuration, JPAImplementation.class);
+        checkImplementationType(configuration, 
AMImplementationType.AUTH_MODULE_CONFIGURATIONS);
+        return configurations.contains((JPAImplementation) configuration)
+                || configurations.add((JPAImplementation) configuration);
+    }
+
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationPostProcessor.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationPostProcessor.java
new file mode 100644
index 0000000..721194f
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationPostProcessor.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.authentication;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+
+@Entity
+@Table(name = JPAAuthenticationPostProcessor.TABLE)
+public class JPAAuthenticationPostProcessor 
+        extends AbstractAuthenticationProcessor implements 
AuthenticationPostProcessor  {
+
+    private static final long serialVersionUID = 8759966056325625080L;
+
+    public static final String TABLE = "AuthenticationPostProcessor";
+
+    @NotNull
+    private String defaultSuccessLoginURL;
+
+    @NotNull
+    private String defaultFailureLoginURL;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = TABLE + "Actions",
+            joinColumns =
+            @JoinColumn(name = "authentication_post_processor"),
+            inverseJoinColumns =
+            @JoinColumn(name = "implementation_id"))
+    private List<JPAImplementation> authenticationPostProcessing = new 
ArrayList<>();
+
+    @Override
+    public String getDefaultSuccessLoginURL() {
+        return defaultSuccessLoginURL;
+    }
+
+    @Override
+    public String getDefaultFailureLoginURL() {
+        return defaultFailureLoginURL;
+    }
+
+    @Override
+    public List<? extends Implementation> getAuthenticationPostProcessing() {
+        return authenticationPostProcessing;
+    }
+
+    @Override
+    public void setDefaultSuccessLoginURL(final String defaultSuccessLoginURL) 
{
+        this.defaultSuccessLoginURL = defaultSuccessLoginURL;
+    }
+
+    @Override
+    public void setDefaultFailureLoginURL(final String defaultFailureLoginURL) 
{
+        this.defaultFailureLoginURL = defaultFailureLoginURL;
+    }
+
+    @Override
+    public boolean addAuthPostProcessing(final Implementation 
authPreProcessing) {
+        checkType(authPreProcessing, JPAImplementation.class);
+        checkImplementationType(authPreProcessing, 
AMImplementationType.AUTH_POST_PROCESSING);
+        return authenticationPostProcessing.contains((JPAImplementation) 
authPreProcessing)
+                || authenticationPostProcessing.add((JPAImplementation) 
authPreProcessing);
+    }
+}
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationPreProcessor.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationPreProcessor.java
new file mode 100644
index 0000000..9c36478
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/authentication/JPAAuthenticationPreProcessor.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.authentication;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+
+@Entity
+@Table(name = JPAAuthenticationPreProcessor.TABLE)
+public class JPAAuthenticationPreProcessor 
+        extends AbstractAuthenticationProcessor implements 
AuthenticationPreProcessor  {
+
+    private static final long serialVersionUID = -3064505653663946579L;
+
+    public static final String TABLE = "AuthenticationPreProcessor";
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = TABLE + "Actions",
+            joinColumns =
+            @JoinColumn(name = "authentication_pre_processor"),
+            inverseJoinColumns =
+            @JoinColumn(name = "implementation_id"))
+    private List<JPAImplementation> authenticationPreProcessing = new 
ArrayList<>();
+
+    @Override
+    public List<? extends Implementation> getAuthenticationPreProcessing() {
+        return authenticationPreProcessing;
+    }
+
+    @Override
+    public boolean addAuthPreProcessing(final Implementation 
authPreProcessing) {
+        checkType(authPreProcessing, JPAImplementation.class);
+        checkImplementationType(authPreProcessing, 
AMImplementationType.AUTH_PRE_PROCESSING);
+        return authenticationPreProcessing.contains((JPAImplementation) 
authPreProcessing)
+                || authenticationPreProcessing.add((JPAImplementation) 
authPreProcessing);
+    }
+
+}
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
new file mode 100644
index 0000000..4c6221e
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccessPolicy.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.policy;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
+
+@Entity
+@Table(name = JPAAccessPolicy.TABLE)
+public class JPAAccessPolicy extends AbstractPolicy implements AccessPolicy {
+
+    private static final long serialVersionUID = -6284704337579924774L;
+
+    public static final String TABLE = "AccessPolicy";
+
+}
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
new file mode 100644
index 0000000..9ea9cea
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAuthenticationPolicy.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.policy;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.jpa.entity.authentication.JPAAuthenticationPreProcessor;
+
+@Entity
+@Table(name = JPAAuthenticationPolicy.TABLE)
+public class JPAAuthenticationPolicy extends AbstractPolicy implements 
AuthenticationPolicy {
+
+    private static final long serialVersionUID = -4190607009908888884L;
+
+    public static final String TABLE = "AuthenticationPolicy";
+
+    @Column(unique = true, nullable = false)
+    private String name;
+
+    @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" }))
+    private List<JPAImplementation> configurations = new ArrayList<>();
+
+    private int maxAuthenticationAttempts;
+
+    private int authenticationAttemptsInterval;
+
+    private int authenticationFailureLockoutDuration;
+
+    private String lockoutAttributeName;
+
+    private String lockoutAttributeValue;
+
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = 
FetchType.EAGER, mappedBy =
+            "authenticationPolicy")
+    private JPAAuthenticationPostProcessor authenticationPostProcessor;
+
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = 
FetchType.EAGER, mappedBy =
+            "authenticationPolicy")
+    private JPAAuthenticationPreProcessor authenticationPreProcessor;
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public int getMaxAuthenticationAttempts() {
+        return maxAuthenticationAttempts;
+    }
+
+    @Override
+    public int getAuthenticationAttemptsInterval() {
+        return authenticationAttemptsInterval;
+    }
+
+    @Override
+    public int getAuthenticationFailureLockoutDuration() {
+        return authenticationFailureLockoutDuration;
+    }
+
+    @Override
+    public String getLockoutAttributeName() {
+        return lockoutAttributeName;
+    }
+
+    @Override
+    public String getLockoutAttributeValue() {
+        return lockoutAttributeValue;
+    }
+
+    @Override
+    public AuthenticationPostProcessor getAuthenticationPostProcessor() {
+        return authenticationPostProcessor;
+    }
+
+    @Override
+    public AuthenticationPreProcessor getAuthenticationPreProcessor() {
+        return authenticationPreProcessor;
+    }
+
+    @Override
+    public List<? extends Implementation> getConfigurations() {
+        return configurations;
+    }
+
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void setMaxAuthenticationAttempts(final int 
maxAuthenticationAttempts) {
+        this.maxAuthenticationAttempts = maxAuthenticationAttempts;
+    }
+
+    @Override
+    public void setAuthenticationAttemptsInterval(final int 
authenticationAttemptsInterval) {
+        this.authenticationAttemptsInterval = authenticationAttemptsInterval;
+    }
+
+    @Override
+    public void setAuthenticationFailureLockoutDuration(final int 
authenticationFailureLockoutDuration) {
+        this.authenticationFailureLockoutDuration = 
authenticationFailureLockoutDuration;
+    }
+
+    @Override
+    public void setLockoutAttributeName(final String lockoutAttributeName) {
+        this.lockoutAttributeName = lockoutAttributeName;
+    }
+
+    @Override
+    public void setLockoutAttributeValue(final String lockoutAttributeValue) {
+        this.lockoutAttributeValue = lockoutAttributeValue;
+    }
+
+    @Override
+    public void setAuthenticationPostProcessor(final 
AuthenticationPostProcessor authenticationPostProcessor) {
+        checkType(authenticationPostProcessor, 
JPAAuthenticationPostProcessor.class);
+        this.authenticationPostProcessor = (JPAAuthenticationPostProcessor) 
authenticationPostProcessor;
+    }
+
+    @Override
+    public void setAuthenticationPreProcessor(final AuthenticationPreProcessor 
authenticationPreProcessor) {
+        checkType(authenticationPreProcessor, 
JPAAuthenticationPreProcessor.class);
+        this.authenticationPreProcessor = (JPAAuthenticationPreProcessor) 
authenticationPreProcessor;
+    }
+
+    @Override
+    public boolean addConfiguration(final Implementation configuration) {
+        checkType(configuration, JPAImplementation.class);
+        checkImplementationType(configuration, 
AMImplementationType.AUTH_POLICY_CONFIGURATIONS);
+        return configurations.contains((JPAImplementation) configuration)
+                || configurations.add((JPAImplementation) configuration);
+    }
+
+}
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationChainTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationChainTest.java
new file mode 100644
index 0000000..9ad6716
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationChainTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.util.List;
+import java.util.UUID;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationChainDAO;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationChain;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional("Master")
+public class AuthenticationChainTest extends AbstractTest {
+
+    @Autowired
+    private AuthenticationChainDAO authenticationChainDAO;
+
+    @Autowired
+    private ImplementationDAO implementationDAO;
+
+    @Test
+    public void find() {
+        AuthenticationChain authenticationChain = authenticationChainDAO.find(
+                "4735ce66-aa3f-416b-b810-9b2c1d25ada7");
+        assertNotNull(authenticationChain);
+
+        authenticationChain = 
authenticationChainDAO.find(UUID.randomUUID().toString());
+        assertNull(authenticationChain);
+    }
+
+    @Test
+    public void findAll() {
+        List<AuthenticationChain> authenticationChains = 
authenticationChainDAO.findAll();
+        assertNotNull(authenticationChains);
+        assertEquals(1, authenticationChains.size());
+    }
+
+    @Test
+    public void save() {
+        Implementation authenticationChainRule = 
entityFactory.newEntity(Implementation.class);
+        authenticationChainRule.setKey(UUID.randomUUID().toString());
+        authenticationChainRule.setEngine(ImplementationEngine.JAVA);
+        authenticationChainRule.setType(AMImplementationType.AUTH_CHAIN_RULES);
+        authenticationChainRule.setBody(POJOHelper.serialize(""));
+
+        int beforeCount = authenticationChainDAO.findAll().size();
+
+        authenticationChainRule = 
implementationDAO.save(authenticationChainRule);
+
+        assertNotNull(authenticationChainRule);
+        assertNotNull(authenticationChainRule.getKey());
+
+        AuthenticationChain authenticationChain = 
entityFactory.newEntity(AuthenticationChain.class);
+        authenticationChain.setName("AuthenticationChainTest");
+        authenticationChain.add(authenticationChainRule);
+        authenticationChainDAO.save(authenticationChain);
+
+        assertNotNull(authenticationChain);
+        assertNotNull(authenticationChain.getKey());
+
+        int afterCount = authenticationChainDAO.findAll().size();
+        assertEquals(afterCount, beforeCount + 1);
+    }
+
+    @Test
+    public void delete() {
+        AuthenticationChain authenticationChain = authenticationChainDAO.find(
+                "4735ce66-aa3f-416b-b810-9b2c1d25ada7");
+        assertNotNull(authenticationChain);
+
+        authenticationChainDAO.delete("4735ce66-aa3f-416b-b810-9b2c1d25ada7");
+
+        authenticationChain = 
authenticationChainDAO.find("4735ce66-aa3f-416b-b810-9b2c1d25ada7");
+        assertNull(authenticationChain);
+    }
+
+}
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationModuleTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationModuleTest.java
new file mode 100644
index 0000000..8802aca
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationModuleTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.util.List;
+import java.util.UUID;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationModuleDAO;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationModule;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional("Master")
+public class AuthenticationModuleTest extends AbstractTest {
+
+    @Autowired
+    private AuthenticationModuleDAO authenticationModuleDAO;
+
+    @Autowired
+    private ImplementationDAO implementationDAO;
+
+    @Test
+    public void find() {
+        AuthenticationModule athAuthenticationModule = 
authenticationModuleDAO.find(
+                "be456831-593d-4003-b273-4c3fb61700df");
+        assertNotNull(athAuthenticationModule);
+
+        athAuthenticationModule = 
authenticationModuleDAO.find(UUID.randomUUID().toString());
+        assertNull(athAuthenticationModule);
+    }
+
+    @Test
+    public void findAll() {
+        List<AuthenticationModule> athAuthenticationModules = 
authenticationModuleDAO.findAll();
+        assertNotNull(athAuthenticationModules);
+        assertEquals(1, athAuthenticationModules.size());
+    }
+
+    @Test
+    public void save() {
+        Implementation authentificationModuleConf = 
entityFactory.newEntity(Implementation.class);
+        authentificationModuleConf.setKey(UUID.randomUUID().toString());
+        authentificationModuleConf.setEngine(ImplementationEngine.JAVA);
+        
authentificationModuleConf.setType(AMImplementationType.AUTH_MODULE_CONFIGURATIONS);
+        authentificationModuleConf.setBody(POJOHelper.serialize(""));
+
+        int beforeCount = authenticationModuleDAO.findAll().size();
+
+        authentificationModuleConf = 
implementationDAO.save(authentificationModuleConf);
+
+        assertNotNull(authentificationModuleConf);
+        assertNotNull(authentificationModuleConf.getKey());
+
+        AuthenticationModule authenticationModule = 
entityFactory.newEntity(AuthenticationModule.class);
+        authenticationModule.setName("AuthenticationModuleTest");
+        authenticationModule.setTraceLevel(TraceLevel.FAILURES);
+        authenticationModule.add(authentificationModuleConf);
+        authenticationModuleDAO.save(authenticationModule);
+
+        assertNotNull(authenticationModule);
+        assertNotNull(authenticationModule.getKey());
+
+        int afterCount = authenticationModuleDAO.findAll().size();
+        assertEquals(afterCount, beforeCount + 1);
+    }
+
+    @Test
+    public void delete() {
+        AuthenticationModule athAuthenticationModule = 
authenticationModuleDAO.find(
+                "be456831-593d-4003-b273-4c3fb61700df");
+        assertNotNull(athAuthenticationModule);
+
+        authenticationModuleDAO.delete("be456831-593d-4003-b273-4c3fb61700df");
+
+        athAuthenticationModule = 
authenticationModuleDAO.find("be456831-593d-4003-b273-4c3fb61700df");
+        assertNull(athAuthenticationModule);
+    }
+
+}
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationProcessorTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationProcessorTest.java
new file mode 100644
index 0000000..fdc526c
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthenticationProcessorTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.AMImplementationType;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationPolicyRule;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationProcessorDAO;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.entity.Implementation;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationProcessor;
+
+@Transactional("Master")
+public class AuthenticationProcessorTest extends AbstractTest {
+
+    @Autowired
+    private AuthenticationProcessorDAO authenticationProcessorDAO;
+
+    @Autowired
+    private ImplementationDAO implementationDAO;
+
+    @Test
+    public void findAll() {
+        List<AuthenticationProcessor> processors = 
authenticationProcessorDAO.findAll();
+        assertNotNull(processors);
+        assertFalse(processors.isEmpty());
+    }
+
+    @Test
+    public void findByKey() {
+        AuthenticationProcessor authPostProcessor =
+                
authenticationProcessorDAO.find("2460e430-ce67-41a5-86ed-ea0a4e78c0a3");
+        assertNotNull(authPostProcessor);
+
+        AuthenticationProcessor authPreProcessor =
+                
authenticationProcessorDAO.find("c413566e-8859-11e9-bc42-526af7764f64");
+        assertNotNull(authPreProcessor);
+    }
+
+    @Test
+    public void findByType() {
+        List<AuthenticationPostProcessor> processors = 
authenticationProcessorDAO.
+                find(AuthenticationPostProcessor.class);
+        assertNotNull(processors);
+        assertFalse(processors.isEmpty());
+    }
+
+    @Test
+    public void create() {
+
+        AuthenticationPostProcessor authenticationPostProcessor =
+                entityFactory.newEntity(AuthenticationPostProcessor.class);
+        authenticationPostProcessor.setDefaultFailureLoginURL("login/error");
+        authenticationPostProcessor.setDefaultSuccessLoginURL("login");
+
+        Implementation postProcessing = 
entityFactory.newEntity(Implementation.class);
+        postProcessing.setKey("PostProcessingTest");
+        postProcessing.setEngine(ImplementationEngine.JAVA);
+        postProcessing.setType(AMImplementationType.AUTH_POST_PROCESSING);
+        postProcessing.setBody(AuthenticationPolicyRule.class.getName());
+        postProcessing = implementationDAO.save(postProcessing);
+        authenticationPostProcessor.addAuthPostProcessing(postProcessing);
+
+        AuthenticationPreProcessor authenticationPreProcessor =
+                entityFactory.newEntity(AuthenticationPreProcessor.class);
+
+        Implementation preProcessing = 
entityFactory.newEntity(Implementation.class);
+        preProcessing.setKey("PreProcessingTest");
+        preProcessing.setEngine(ImplementationEngine.JAVA);
+        preProcessing.setType(AMImplementationType.AUTH_PRE_PROCESSING);
+        preProcessing.setBody(AuthenticationPolicyRule.class.getName());
+        preProcessing = implementationDAO.save(preProcessing);
+        authenticationPreProcessor.addAuthPreProcessing(preProcessing);
+    }
+
+    @Test
+    public void update() {
+        AuthenticationPostProcessor authPostProcessor =
+                
authenticationProcessorDAO.find("2460e430-ce67-41a5-86ed-ea0a4e78c0a3");
+        assertNotNull(authPostProcessor);
+        assertEquals(1, 
authPostProcessor.getAuthenticationPostProcessing().size());
+        assertEquals("login", authPostProcessor.getDefaultSuccessLoginURL());
+
+        authPostProcessor.setDefaultSuccessLoginURL("login/home");
+        authPostProcessor = authenticationProcessorDAO.save(authPostProcessor);
+
+        assertNotNull(authPostProcessor);
+        assertEquals("login/home", 
authPostProcessor.getDefaultSuccessLoginURL());
+    }
+
+    @Test
+    public void delete() {
+        AuthenticationPostProcessor authPostProcessor =
+                
authenticationProcessorDAO.find("2460e430-ce67-41a5-86ed-ea0a4e78c0a3");
+        assertNotNull(authPostProcessor);
+
+        authenticationProcessorDAO.delete(authPostProcessor);
+
+        authPostProcessor = 
authenticationProcessorDAO.find("2460e430-ce67-41a5-86ed-ea0a4e78c0a3");
+        assertNull(authPostProcessor);
+    }
+}
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 21297d0..533eca0 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
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.List;
+import org.apache.syncope.common.lib.types.AMImplementationType;
 import org.apache.syncope.common.lib.types.IdMImplementationType;
 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
@@ -44,7 +45,7 @@ public class ImplementationTest extends AbstractTest {
         List<Implementation> implementations = implementationDAO.findAll();
         assertFalse(implementations.isEmpty());
 
-        assertEquals(18, implementations.size());
+        assertEquals(23, implementations.size());
 
         implementations = 
implementationDAO.findByType(IdMImplementationType.PULL_ACTIONS);
         assertEquals(1, implementations.size());
@@ -72,6 +73,18 @@ public class ImplementationTest extends AbstractTest {
 
         implementations = 
implementationDAO.findByType(IdMImplementationType.PUSH_CORRELATION_RULE);
         assertEquals(1, implementations.size());
+
+        implementations = 
implementationDAO.findByType(AMImplementationType.AUTH_MODULE_CONFIGURATIONS);
+        assertEquals(1, implementations.size());
+
+        implementations = 
implementationDAO.findByType(AMImplementationType.AUTH_POLICY_CONFIGURATIONS);
+        assertEquals(1, implementations.size());
+
+        implementations = 
implementationDAO.findByType(AMImplementationType.AUTH_POST_PROCESSING);
+        assertEquals(1, implementations.size());
+
+        implementations = 
implementationDAO.findByType(AMImplementationType.AUTH_PRE_PROCESSING);
+        assertEquals(1, implementations.size());
     }
 
     @Test
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
index 0b2ed8f..b971a5c 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -29,12 +29,14 @@ import java.util.UUID;
 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
 import org.apache.syncope.common.lib.policy.DefaultPullCorrelationRuleConf;
 import org.apache.syncope.common.lib.policy.DefaultPushCorrelationRuleConf;
+import org.apache.syncope.common.lib.types.AMImplementationType;
 import org.apache.syncope.common.lib.types.ConflictResolutionAction;
 import org.apache.syncope.common.lib.types.IdMImplementationType;
 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.AuthenticationPolicyRule;
 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
@@ -46,6 +48,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.dao.PullCorrelationRule;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPostProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.authentication.AuthenticationPreProcessor;
+import 
org.apache.syncope.core.persistence.api.entity.policy.AuthenticationPolicy;
 import 
org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
 import 
org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
@@ -93,6 +98,9 @@ public class PolicyTest extends AbstractTest {
         assertNotNull(pushCRConf);
         assertEquals(1, pushCRConf.getSchemas().size());
         assertTrue(pushCRConf.getSchemas().contains("email"));
+
+        AuthenticationPolicy authenticationPolicy = 
policyDAO.find("b912a0d4-a890-416f-9ab8-84ab077eb028");
+        assertNotNull(authenticationPolicy);
     }
 
     @Test
@@ -144,6 +152,54 @@ public class PolicyTest extends AbstractTest {
                 
policy.getCorrelationRule(anyTypeDAO.findUser()).get().getImplementation().getKey());
         assertEquals(pullGRuleName,
                 
policy.getCorrelationRule(anyTypeDAO.findGroup()).get().getImplementation().getKey());
+
+        AuthenticationPolicy authenticationPolicy = 
entityFactory.newEntity(AuthenticationPolicy.class);
+        authenticationPolicy.setAuthenticationAttemptsInterval(1);
+        authenticationPolicy.setAuthenticationFailureLockoutDuration(10);
+
+        AuthenticationPostProcessor authenticationPostProcessor =
+                entityFactory.newEntity(AuthenticationPostProcessor.class);
+        authenticationPostProcessor.setDefaultFailureLoginURL("login/error");
+        authenticationPostProcessor.setDefaultSuccessLoginURL("login");
+        
authenticationPostProcessor.setAuthenticationPolicy(authenticationPolicy);
+        Implementation postProcessing = 
entityFactory.newEntity(Implementation.class);
+        postProcessing.setKey("PostProcessingKey");
+        postProcessing.setEngine(ImplementationEngine.JAVA);
+        postProcessing.setType(AMImplementationType.AUTH_POST_PROCESSING);
+        postProcessing.setBody(AuthenticationPolicyRule.class.getName());
+        postProcessing = implementationDAO.save(postProcessing);
+        authenticationPostProcessor.addAuthPostProcessing(postProcessing);
+        
authenticationPolicy.setAuthenticationPostProcessor(authenticationPostProcessor);
+
+        AuthenticationPreProcessor authenticationPreProcessor =
+                entityFactory.newEntity(AuthenticationPreProcessor.class);
+        
authenticationPreProcessor.setAuthenticationPolicy(authenticationPolicy);
+        Implementation preProcessing = 
entityFactory.newEntity(Implementation.class);
+        preProcessing.setKey("PreProcessingKey");
+        preProcessing.setEngine(ImplementationEngine.JAVA);
+        preProcessing.setType(AMImplementationType.AUTH_PRE_PROCESSING);
+        preProcessing.setBody(AuthenticationPolicyRule.class.getName());
+        preProcessing = implementationDAO.save(preProcessing);
+        authenticationPreProcessor.addAuthPreProcessing(preProcessing);
+        
authenticationPolicy.setAuthenticationPreProcessor(authenticationPreProcessor);
+
+        authenticationPolicy.setDescription("Syncope Account Policy");
+        authenticationPolicy.setLockoutAttributeName("locked");
+        authenticationPolicy.setLockoutAttributeValue("true");
+        authenticationPolicy.setMaxAuthenticationAttempts(5);
+
+        Implementation type = entityFactory.newEntity(Implementation.class);
+        type.setKey("AuthPolicyConfKey");
+        type.setEngine(ImplementationEngine.JAVA);
+        type.setType(AMImplementationType.AUTH_POLICY_CONFIGURATIONS);
+        type.setBody(AuthenticationPolicyRule.class.getName());
+        type = implementationDAO.save(type);
+
+        authenticationPolicy.addConfiguration(type);
+        authenticationPolicy = policyDAO.save(authenticationPolicy);
+
+        assertNotNull(authenticationPolicy);
+
     }
 
     @Test
@@ -186,4 +242,15 @@ public class PolicyTest extends AbstractTest {
         Policy actual = policyDAO.find("66691e96-285f-4464-bc19-e68384ea4c85");
         assertNull(actual);
     }
+
+    @Test
+    public void deleteAuthenticationPolicy() {
+        Policy policy = policyDAO.find("b912a0d4-a890-416f-9ab8-84ab077eb028");
+        assertNotNull(policy);
+
+        policyDAO.delete(policy);
+
+        Policy actual = policyDAO.find("b912a0d4-a890-416f-9ab8-84ab077eb028");
+        assertNull(actual);
+    }
 }
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml 
b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 0809c01..bec26cd 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -44,6 +44,11 @@ under the License.
                   
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"/>
 
+  <AuthenticationPolicy id="b912a0d4-a890-416f-9ab8-84ab077eb028" 
name="DefaultAuthenticationPolicy"/>
+  <Implementation id="DefaultAuthenticationPolicyConf" 
type="AUTH_POLICY_CONFIGURATIONS" engine="JAVA"
+                  
body='{"@class":"org.apache.syncope.common.lib.authentication.DefaultAuthenticationPolicyConf","name":"DefaultAuthenticationPolicyConf"}'/>
+  <AuthenticationPolicyConf 
authentication_policy_id="b912a0d4-a890-416f-9ab8-84ab077eb028" 
implementation_id="DefaultAuthenticationPolicyConf"/>
+  
   <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"/>
   
@@ -65,7 +70,8 @@ under the License.
       
   <AnyTypeClass id="csv"/>
 
-  <Realm id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" name="/" 
passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1"/>
+  <Realm id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" name="/" 
passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1"
+         authenticationPolicy_id="b912a0d4-a890-416f-9ab8-84ab077eb028"/>
   <Realm id="722f3d84-9c2b-4525-8f6e-e4b82c55a36c" name="odd" 
          parent_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" 
accountPolicy_id="06e2ed52-6966-44aa-a177-a0ca7434201f"/>
   <Realm id="c5b75db1-fce7-470f-b780-3b9934d82a9d" name="even" 
@@ -2427,4 +2433,27 @@ $$ }&#10;
 
   <GatewayRoute id="ec7bada2-3dd6-460c-8441-65521d005ffa" name="basic1" 
target="http://httpbin.org:80"; status="PUBLISHED"
                 
predicates="[{&quot;cond&quot;:null,&quot;factory&quot;:&quot;METHOD&quot;,&quot;args&quot;:&quot;GET&quot;}]"/>
+    
+  <AuthenticationModule id="be456831-593d-4003-b273-4c3fb61700df" 
name="TestAuthModule"/>
+  <Implementation id="DefaultAuthenticationModuleConf" 
type="AUTH_MODULE_CONFIGURATIONS" engine="JAVA"
+                  
body='{"@class":"org.apache.syncope.common.lib.authentication.DefaultAuthenticationModuleConf","name":"DefaultAuthenticationModuleConf"}'/>
+  <AuthenticationModuleConf 
authentication_module_id="be456831-593d-4003-b273-4c3fb61700df" 
implementation_id="DefaultAuthenticationModuleConf"/>
+  
+  <AuthenticationChain id="4735ce66-aa3f-416b-b810-9b2c1d25ada7" 
name="ChainAuthenticationPolicy"/>
+  <Implementation id="ChainAuthenticationPolicyConf" 
type="AUTH_CHAIN_CONFIGURATIONS" engine="JAVA"
+                  
body='{"@class":"org.apache.syncope.common.lib.authentication.ChainAuthenticationPolicyConf","name":"ChainAuthenticationPolicyConf"}'/>
+  <AuthenticationChainConf 
authentication_chain_id="4735ce66-aa3f-416b-b810-9b2c1d25ada7" 
implementation_id="ChainAuthenticationPolicyConf"/>
+  
+  <AuthenticationPostProcessor id="2460e430-ce67-41a5-86ed-ea0a4e78c0a3" 
name="TestPostProcessor" 
authenticationPolicy_id="b912a0d4-a890-416f-9ab8-84ab077eb028"
+  defaultSuccessLoginURL="login"/>
+  <Implementation id="TestAuthPostProcessorAction" type="AUTH_POST_PROCESSING" 
engine="JAVA"
+                  
body='{"@class":"org.apache.syncope.common.lib.authentication.TestAuthPostProcessor","name":"TestAuthPostProcessorAction"}'/>
+  <AuthenticationPostProcessorActions 
authentication_post_processor="2460e430-ce67-41a5-86ed-ea0a4e78c0a3" 
+                                      
implementation_id="TestAuthPostProcessorAction" />  
+  
+  <AuthenticationPreProcessor id="c413566e-8859-11e9-bc42-526af7764f64" 
name="TestPreProcessor" 
authenticationPolicy_id="b912a0d4-a890-416f-9ab8-84ab077eb028"/>  
+  <Implementation id="TestAuthPreProcessorAction" type="AUTH_PRE_PROCESSING" 
engine="JAVA"
+                  
body='{"@class":"org.apache.syncope.common.lib.authentication.TestAuthPreProcessorAction","name":"TestAuthPreProcessorAction"}'/>
+  <AuthenticationPreProcessorActions 
authentication_pre_processor="c413566e-8859-11e9-bc42-526af7764f64" 
implementation_id="TestAuthPreProcessorAction"/>
+  
 </dataset>

Reply via email to