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

[2/2] syncope git commit: Upgrading the SAML2SP ext to the latest changes

Upgrading the SAML2SP ext to the latest changes


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

Branch: refs/heads/master
Commit: d685eda851a9a4a916a718e5f7a66a278dcc9456
Parents: 89fe831
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Aug 2 12:47:45 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Aug 2 12:47:57 2017 +0200

----------------------------------------------------------------------
 .../client/console/panels/DirectoryPanel.java   |  4 +-
 .../syncope/common/lib/to/ItemContainerTO.java  |  2 +-
 .../apache/syncope/common/lib/to/MappingTO.java |  2 +-
 .../apache/syncope/common/lib/to/OrgUnitTO.java |  2 +-
 .../syncope/core/logic/AccessTokenLogic.java    | 28 +++++++-
 .../jpa/entity/resource/JPAOrgUnitItem.java     |  2 +-
 .../api/data/AccessTokenDataBinder.java         |  5 +-
 .../java/data/AccessTokenDataBinderImpl.java    | 33 ++-------
 .../spring/security/SyncopeJWTSSOProvider.java  | 19 ++---
 .../console/panels/SAML2IdPsDirectoryPanel.java | 20 ++++++
 .../console/wizards/SAML2IdPMappingPanel.java   |  2 +-
 .../console/wizards/SAML2IdPWizardBuilder.java  |  3 +-
 .../panels/SAML2IdPsDirectoryPanel.properties   |  1 +
 .../SAML2IdPsDirectoryPanel_it.properties       |  1 +
 .../SAML2IdPsDirectoryPanel_pt_BR.properties    |  1 +
 .../SAML2IdPsDirectoryPanel_ru.properties       |  1 +
 .../syncope/common/lib/to/SAML2IdPTO.java       | 24 ++++---
 .../apache/syncope/core/logic/SAML2SPLogic.java | 22 +++++-
 .../core/persistence/api/entity/SAML2IdP.java   |  9 ++-
 .../persistence/api/entity/SAML2IdPItem.java    | 28 ++++++++
 .../jpa/entity/JPASAML2EntityFactory.java       |  4 +-
 .../persistence/jpa/entity/JPASAML2IdP.java     | 25 ++++---
 .../persistence/jpa/entity/JPASAML2IdPItem.java | 73 ++++++++++++++++++++
 .../validation/entity/SAML2IdPValidator.java    | 14 ++--
 .../java/data/SAML2IdPDataBinderImpl.java       | 33 ++++-----
 .../apache/syncope/fit/core/SAML2ITCase.java    |  4 +-
 26 files changed, 257 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
index e066088..55cca0f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
@@ -105,7 +105,7 @@ public abstract class DirectoryPanel<
 
     protected final BaseModal<W> displayAttributeModal = new BaseModal<>("outer");
 
-    private ActionLinksTogglePanel<T> actionTogglePanel;
+    protected ActionLinksTogglePanel<T> actionTogglePanel;
 
     /**
      * Create simple unfiltered search result panel.
@@ -139,7 +139,7 @@ public abstract class DirectoryPanel<
         super(id, wizardInModal);
         setOutputMarkupId(true);
 
-        actionTogglePanel = new ActionLinksTogglePanel<T>("outer", builder.getPageRef());
+        actionTogglePanel = new ActionLinksTogglePanel<>("outer", builder.getPageRef());
         addOuterObject(actionTogglePanel);
 
         addOuterObject(altDefaultModal);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
index 6975b2c..a76fe10 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
@@ -22,7 +22,7 @@ import java.util.List;
 
 public interface ItemContainerTO {
 
-    void setConnObjectLink(String connObjectLink);
+    ItemTO getConnObjectKeyItem();
 
     boolean setConnObjectKeyItem(ItemTO connObjectKeyItem);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
index 8fe6224..23c91ac 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
@@ -45,11 +45,11 @@ public class MappingTO extends AbstractBaseBean implements ItemContainerTO {
         return connObjectLink;
     }
 
-    @Override
     public void setConnObjectLink(final String connObjectLink) {
         this.connObjectLink = connObjectLink;
     }
 
+    @Override
     public ItemTO getConnObjectKeyItem() {
         return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
index 1290c0c..c18b05e 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
@@ -75,11 +75,11 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO, ItemContain
         return connObjectLink;
     }
 
-    @Override
     public void setConnObjectLink(final String connObjectLink) {
         this.connObjectLink = connObjectLink;
     }
 
+    @Override
     public ItemTO getConnObjectKeyItem() {
         return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
index e6b0099..f1a39c1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.logic;
 
+import static org.apache.syncope.core.logic.AbstractLogic.LOG;
+
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -28,13 +30,16 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -42,6 +47,8 @@ import org.springframework.stereotype.Component;
 @Component
 public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO> {
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
@@ -51,13 +58,30 @@ public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO>
     @Autowired
     private AccessTokenDAO accessTokenDAO;
 
+    private byte[] getAuthorities() {
+        byte[] authorities = null;
+        try {
+            authorities = ENCRYPTOR.encode(POJOHelper.serialize(
+                    AuthContextUtils.getAuthorities()), CipherAlgorithm.AES).
+                    getBytes();
+        } catch (Exception e) {
+            LOG.error("Could not fetch authorities", e);
+        }
+
+        return authorities;
+    }
+
     @PreAuthorize("isAuthenticated()")
     public Pair<String, Date> login() {
         if (anonymousUser.equals(AuthContextUtils.getUsername())) {
             throw new IllegalArgumentException(anonymousUser + " cannot be granted an access token");
         }
 
-        return binder.create(AuthContextUtils.getUsername(), Collections.<String, Object>emptyMap(), false);
+        return binder.create(
+                AuthContextUtils.getUsername(),
+                Collections.<String, Object>emptyMap(),
+                getAuthorities(),
+                false);
     }
 
     @PreAuthorize("isAuthenticated()")
@@ -67,7 +91,7 @@ public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO>
             throw new NotFoundException("AccessToken for " + AuthContextUtils.getUsername());
         }
 
-        return binder.update(accessToken);
+        return binder.update(accessToken, getAuthorities());
     }
 
     @PreAuthorize("isAuthenticated()")

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
index e356ff2..24f59ce 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
@@ -45,7 +45,7 @@ public class JPAOrgUnitItem extends AbstractItem implements OrgUnitItem {
     private JPAOrgUnit orgUnit;
 
     /**
-     * (Optional) classes for MappingItem transformation.
+     * (Optional) classes for Item transformation.
      */
     @ElementCollection(fetch = FetchType.EAGER)
     @Column(name = "transformerClassName")

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
index 065f5f7..4bb64aa 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
@@ -29,9 +29,10 @@ public interface AccessTokenDataBinder {
 
     Triple<String, String, Date> generateJWT(String subject, long duration, Map<String, Object> claims);
 
-    Pair<String, Date> create(String subject, Map<String, Object> claims, boolean replaceExisting);
+    Pair<String, Date> create(
+            String subject, Map<String, Object> claims, byte[] authorities, boolean replaceExisting);
 
-    Pair<String, Date> update(AccessToken accessToken);
+    Pair<String, Date> update(AccessToken accessToken, byte[] authorities);
 
     AccessTokenTO getAccessTokenTO(AccessToken accessToken);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
index d886db6..350f1ed 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
@@ -33,29 +33,19 @@ import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.BeanUtils;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.DefaultCredentialChecker;
-import org.apache.syncope.core.spring.security.Encryptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
 
-    private static final Logger LOG = LoggerFactory.getLogger(AccessTokenDataBinder.class);
-
-    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
     private static final String[] IGNORE_PROPERTIES = { "owner" };
 
     private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
@@ -112,7 +102,10 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
 
     @Override
     public Pair<String, Date> create(
-            final String subject, final Map<String, Object> claims, final boolean replaceExisting) {
+            final String subject,
+            final Map<String, Object> claims,
+            final byte[] authorities,
+            final boolean replaceExisting) {
 
         String body = null;
         Date expiryTime = null;
@@ -139,13 +132,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
             accessToken.setOwner(subject);
 
             if (!adminUser.equals(accessToken.getOwner())) {
-                try {
-                    accessToken.setAuthorities(ENCRYPTOR.encode(
-                            POJOHelper.serialize(AuthContextUtils.getAuthorities()), CipherAlgorithm.AES).
-                            getBytes());
-                } catch (Exception e) {
-                    LOG.error("Could not store authorities", e);
-                }
+                accessToken.setAuthorities(authorities);
             }
 
             accessTokenDAO.save(accessToken);
@@ -159,7 +146,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
     }
 
     @Override
-    public Pair<String, Date> update(final AccessToken accessToken) {
+    public Pair<String, Date> update(final AccessToken accessToken, final byte[] authorities) {
         JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(accessToken.getBody());
 
         credentialChecker.checkIsDefaultJWSKeyInUse();
@@ -181,13 +168,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
         accessToken.setExpiryTime(expiryDate);
 
         if (!adminUser.equals(accessToken.getOwner())) {
-            try {
-                accessToken.setAuthorities(ENCRYPTOR.encode(
-                        POJOHelper.serialize(AuthContextUtils.getAuthorities()), CipherAlgorithm.AES).
-                        getBytes());
-            } catch (Exception e) {
-                LOG.error("Could not store authorities", e);
-            }
+            accessToken.setAuthorities(authorities);
         }
 
         accessTokenDAO.save(accessToken);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
index f5d7852..3a20289 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeJWTSSOProvider.java
@@ -84,17 +84,18 @@ public class SyncopeJWTSSOProvider implements JWTSSOProvider {
     @Override
     public Pair<User, Set<SyncopeGrantedAuthority>> resolve(final JwtClaims jwtClaims) {
         User user = userDAO.findByUsername(jwtClaims.getSubject());
-        Set<SyncopeGrantedAuthority> authorities = null;
+        Set<SyncopeGrantedAuthority> authorities = Collections.emptySet();
         if (user != null) {
             AccessToken accessToken = accessTokenDAO.find(jwtClaims.getTokenId());
-            try {
-                authorities = POJOHelper.deserialize(
-                        ENCRYPTOR.decode(new String(accessToken.getAuthorities()), CipherAlgorithm.AES),
-                        new TypeReference<Set<SyncopeGrantedAuthority>>() {
-                });
-            } catch (Throwable t) {
-                LOG.error("Could not read stored authorities", t);
-                authorities = Collections.emptySet();
+            if (accessToken.getAuthorities() != null) {
+                try {
+                    authorities = POJOHelper.deserialize(
+                            ENCRYPTOR.decode(new String(accessToken.getAuthorities()), CipherAlgorithm.AES),
+                            new TypeReference<Set<SyncopeGrantedAuthority>>() {
+                    });
+                } catch (Throwable t) {
+                    LOG.error("Could not read stored authorities", t);
+                }
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
index caa70bf..2ab6d8d 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
@@ -37,6 +37,7 @@ import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
@@ -93,6 +94,25 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
             }
         });
 
+        // need to override to change the menu header
+        actionTogglePanel = new ActionLinksTogglePanel<SAML2IdPTO>("outer", pageRef) {
+
+            private static final long serialVersionUID = -7688359318035249200L;
+
+            @Override
+            public void toggleWithContent(
+                    final AjaxRequestTarget target,
+                    final ActionsPanel<SAML2IdPTO> actionsPanel,
+                    final SAML2IdPTO modelObject) {
+
+                super.toggleWithContent(target, actionsPanel, modelObject);
+                setHeader(target, StringUtils.abbreviate(modelObject.getName(), 25));
+                this.toggle(target, true);
+            }
+
+        };
+        addOuterObject(actionTogglePanel);
+
         addOuterObject(metadataModal);
         setWindowClosedReloadCallback(metadataModal);
         metadataModal.size(Modal.Size.Large);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
index 8ea1671..af13d8f 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
@@ -46,7 +46,7 @@ public class SAML2IdPMappingPanel extends AbstractMappingPanel {
         super(id,
                 mapItemTransformers,
                 jexlTransformers,
-                new ListModel<ItemTO>(idpTO.getMappingItems()),
+                new ListModel<ItemTO>(idpTO.getItems()),
                 true,
                 true,
                 MappingPurpose.NONE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index aa9ea0f..8567dd2 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -132,8 +132,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
 
     @Override
     protected Serializable onApplyInternal(final SAML2IdPTO modelObject) {
-        long connObjectKeyCount = IterableUtils.countMatches(
-                modelObject.getMappingItems(), new Predicate<ItemTO>() {
+        long connObjectKeyCount = IterableUtils.countMatches(modelObject.getItems(), new Predicate<ItemTO>() {
 
             @Override
             public boolean evaluate(final ItemTO item) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
index 8c5125d..f9c6403 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
@@ -20,3 +20,4 @@ logoutSupported=Logout supported
 any.edit=Edit ${entityID}
 connObjectKeyValidation=There must be exactly one Remote Key
 bindingType=Binding
+html.title=metadata

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
index d0ee370..312da5d 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
@@ -20,3 +20,4 @@ logoutSupported=Logout supportato
 any.edit=Modifica ${entityID}
 connObjectKeyValidation=Deve essere definito esattamente una Chiave remota
 bindingType=Binding
+html.title=metadata

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
index 87a0c40..4e053f7 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
@@ -20,3 +20,4 @@ logoutSupported=Logout supported
 any.edit=Alterar ${entityID}
 connObjectKeyValidation=Precisa ser exatamente um Remote Key
 bindingType=Binding
+html.title=metadata

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
index 479faea..8bedf47 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
@@ -20,3 +20,4 @@ logoutSupported=Logout supported
 any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${entityID}
 connObjectKeyValidation=\u0422\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430
 bindingType=Binding
+html.title=metadata

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
index 089908e..ffda86d 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
@@ -33,7 +33,7 @@ import org.apache.syncope.common.lib.types.SAML2BindingType;
 
 @XmlRootElement(name = "saml2idp")
 @XmlType
-public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
+public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContainerTO {
 
     private static final long serialVersionUID = 4426527052873779881L;
 
@@ -51,7 +51,7 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
 
     private boolean logoutSupported;
 
-    private final List<ItemTO> mappingItems = new ArrayList<>();
+    private final List<ItemTO> items = new ArrayList<>();
 
     @Override
     public String getKey() {
@@ -112,8 +112,9 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
         this.logoutSupported = logoutSupported;
     }
 
+    @Override
     public ItemTO getConnObjectKeyItem() {
-        return IterableUtils.find(getMappingItems(), new Predicate<ItemTO>() {
+        return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
 
             @Override
             public boolean evaluate(final ItemTO item) {
@@ -129,25 +130,28 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
         return this.add(connObjectItem);
     }
 
+    @Override
     public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         return connObjectKeyItem == null
                 ? remove(getConnObjectKeyItem())
                 : addConnObjectKeyItem(connObjectKeyItem);
     }
 
-    @XmlElementWrapper(name = "mappingItems")
-    @XmlElement(name = "mappingItem")
-    @JsonProperty("mappingItems")
-    public List<ItemTO> getMappingItems() {
-        return mappingItems;
+    @XmlElementWrapper(name = "items")
+    @XmlElement(name = "item")
+    @JsonProperty("items")
+    @Override
+    public List<ItemTO> getItems() {
+        return items;
     }
 
+    @Override
     public boolean add(final ItemTO item) {
-        return item == null ? false : this.mappingItems.contains(item) || this.mappingItems.add(item);
+        return item == null ? false : this.items.contains(item) || this.items.add(item);
     }
 
     public boolean remove(final ItemTO item) {
-        return this.mappingItems.remove(item);
+        return this.items.remove(item);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index ab999d9..222d3cf 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -46,6 +46,7 @@ import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
 import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -119,6 +120,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.stereotype.Component;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthDataAccessor;
+import org.apache.syncope.core.spring.security.Encryptor;
 
 @Component
 public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
@@ -137,6 +141,8 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
 
     private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     @Autowired
     private AccessTokenDataBinder accessTokenDataBinder;
 
@@ -159,6 +165,9 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
     private IntAttrNameParser intAttrNameParser;
 
     @Autowired
+    private AuthDataAccessor authDataAccessor;
+
+    @Autowired
     private EntityFactory entityFactory;
 
     @Autowired
@@ -532,7 +541,18 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         claims.put(JWT_CLAIM_NAMEID_FORMAT, nameID.getFormat());
         claims.put(JWT_CLAIM_NAMEID_VALUE, nameID.getValue());
         claims.put(JWT_CLAIM_SESSIONINDEX, responseTO.getSessionIndex());
-        Pair<String, Date> accessTokenInfo = accessTokenDataBinder.create(responseTO.getUsername(), claims, true);
+
+        byte[] authorities = null;
+        try {
+            authorities = ENCRYPTOR.encode(POJOHelper.serialize(
+                    authDataAccessor.getAuthorities(responseTO.getUsername())), CipherAlgorithm.AES).
+                    getBytes();
+        } catch (Exception e) {
+            LOG.error("Could not fetch authorities", e);
+        }
+
+        Pair<String, Date> accessTokenInfo =
+                accessTokenDataBinder.create(responseTO.getUsername(), claims, authorities, true);
         responseTO.setAccessToken(accessTokenInfo.getLeft());
         responseTO.setAccessTokenExpiryTime(accessTokenInfo.getRight());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java
index b6fc4c3..7d1a5da 100644
--- a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java
+++ b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java
@@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 
 public interface SAML2IdP extends Entity {
 
@@ -44,12 +43,12 @@ public interface SAML2IdP extends Entity {
 
     void setBindingType(SAML2BindingType bindingType);
 
-    MappingItem getConnObjectKeyItem();
+    SAML2IdPItem getConnObjectKeyItem();
 
-    void setConnObjectKeyItem(MappingItem item);
+    void setConnObjectKeyItem(SAML2IdPItem item);
 
-    boolean add(MappingItem item);
+    boolean add(SAML2IdPItem item);
 
-    List<? extends MappingItem> getMappingItems();
+    List<? extends SAML2IdPItem> getItems();
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdPItem.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdPItem.java b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdPItem.java
new file mode 100644
index 0000000..d9ba314
--- /dev/null
+++ b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdPItem.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+
+public interface SAML2IdPItem extends Item {
+
+    SAML2IdP getIdP();
+
+    void setIdP(SAML2IdP idp);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
index d99d5d9..2277c14 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.SAML2EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -33,11 +34,12 @@ public class JPASAML2EntityFactory implements SAML2EntityFactory {
 
         if (reference.equals(SAML2IdP.class)) {
             result = (E) new JPASAML2IdP();
+        } else if (reference.equals(SAML2IdPItem.class)) {
+            result = (E) new JPASAML2IdPItem();
         } else {
             throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
         }
 
         return result;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java
index 1a41bbc..cf1e3a8 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java
@@ -36,8 +36,7 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem;
 import org.apache.syncope.core.persistence.jpa.validation.entity.SAML2IdPCheck;
 
 @Entity
@@ -60,8 +59,8 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
     @Basic(fetch = FetchType.EAGER)
     private Byte[] metadata;
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
-    private List<JPAMappingItem> mappingItems = new ArrayList<>();
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "idp")
+    private List<JPASAML2IdPItem> items = new ArrayList<>();
 
     @Min(0)
     @Max(1)
@@ -122,29 +121,29 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
     }
 
     @Override
-    public boolean add(final MappingItem item) {
-        checkType(item, JPAMappingItem.class);
-        return mappingItems.contains((JPAMappingItem) item) || mappingItems.add((JPAMappingItem) item);
+    public boolean add(final SAML2IdPItem item) {
+        checkType(item, JPASAML2IdPItem.class);
+        return items.contains((JPASAML2IdPItem) item) || items.add((JPASAML2IdPItem) item);
     }
 
     @Override
-    public List<? extends MappingItem> getMappingItems() {
-        return mappingItems;
+    public List<? extends SAML2IdPItem> getItems() {
+        return items;
     }
 
     @Override
-    public MappingItem getConnObjectKeyItem() {
-        return IterableUtils.find(getMappingItems(), new Predicate<MappingItem>() {
+    public SAML2IdPItem getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<SAML2IdPItem>() {
 
             @Override
-            public boolean evaluate(final MappingItem item) {
+            public boolean evaluate(final SAML2IdPItem item) {
                 return item.isConnObjectKey();
             }
         });
     }
 
     @Override
-    public void setConnObjectKeyItem(final MappingItem item) {
+    public void setConnObjectKeyItem(final SAML2IdPItem item) {
         item.setConnObjectKey(true);
         this.add(item);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java
new file mode 100644
index 0000000..863d068
--- /dev/null
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractItem;
+
+@Entity
+@Table(name = JPASAML2IdPItem.TABLE)
+@Cacheable
+public class JPASAML2IdPItem extends AbstractItem implements SAML2IdPItem {
+
+    public static final String TABLE = "SAML2IdPItem";
+
+    private static final long serialVersionUID = -597417734910639991L;
+
+    @ManyToOne
+    private JPASAML2IdP idp;
+
+    /**
+     * (Optional) classes for Item transformation.
+     */
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "transformerClassName")
+    @CollectionTable(name = TABLE + "_Transformer",
+            joinColumns =
+            @JoinColumn(name = "saml2IdPItemItem_id", referencedColumnName = "id"))
+    private List<String> transformerClassNames = new ArrayList<>();
+
+    @Override
+    public SAML2IdP getIdP() {
+        return idp;
+    }
+
+    @Override
+    public void setIdP(final SAML2IdP idp) {
+        checkType(idp, JPASAML2IdP.class);
+        this.idp = (JPASAML2IdP) idp;
+    }
+
+    @Override
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
index 3e80bed..225c6d1 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
@@ -23,21 +23,21 @@ import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP> {
 
     @Override
     public boolean isValid(final SAML2IdP value, final ConstraintValidatorContext context) {
-        long connObjectKeys = IterableUtils.countMatches(value.getMappingItems(), new Predicate<MappingItem>() {
+        long connObjectKeys = IterableUtils.countMatches(value.getItems(), new Predicate<SAML2IdPItem>() {
 
             @Override
-            public boolean evaluate(final MappingItem item) {
+            public boolean evaluate(final SAML2IdPItem item) {
                 return item.isConnObjectKey();
             }
         });
-        if (!value.getMappingItems().isEmpty() && connObjectKeys != 1) {
+        if (!value.getItems().isEmpty() && connObjectKeys != 1) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidMapping, "Single ConnObjectKey mapping is required")).
                     addPropertyNode("connObjectKey.size").addConstraintViolation();
@@ -46,10 +46,10 @@ public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP
 
         boolean isValid = true;
 
-        long passwords = IterableUtils.countMatches(value.getMappingItems(), new Predicate<MappingItem>() {
+        long passwords = IterableUtils.countMatches(value.getItems(), new Predicate<SAML2IdPItem>() {
 
             @Override
-            public boolean evaluate(final MappingItem item) {
+            public boolean evaluate(final SAML2IdPItem item) {
                 return item.isPassword();
             }
         });
@@ -60,7 +60,7 @@ public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP
             isValid = false;
         }
 
-        for (MappingItem item : value.getMappingItems()) {
+        for (SAML2IdPItem item : value.getItems()) {
             for (String className : item.getTransformerClassNames()) {
                 Class<?> actionsClass = null;
                 boolean isAssignable = false;

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
index f9f16ab..b2668c5 100644
--- a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
+++ b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
@@ -32,12 +32,11 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.SAML2IdPDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.SAML2EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
 import org.apache.syncope.core.provisioning.api.data.SAML2IdPDataBinder;
 import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
@@ -55,7 +54,7 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
 
     private static final Logger LOG = LoggerFactory.getLogger(SAML2IdPDataBinder.class);
 
-    private static final String[] MAPPINGITEM_IGNORE_PROPERTIES = { "key", "mapping", "purpose" };
+    private static final String[] ITEM_IGNORE_PROPERTIES = { "key", "purpose" };
 
     @Autowired
     private AnyTypeDAO anyTypeDAO;
@@ -64,20 +63,17 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
     private SAML2IdPDAO saml2IdPDAO;
 
     @Autowired
-    private EntityFactory entityFactory;
-
-    @Autowired
-    private SAML2EntityFactory saml2EntityFactory;
+    private SAML2EntityFactory entityFactory;
 
     @Autowired
     private IntAttrNameParser intAttrNameParser;
 
     @Override
     public SAML2IdP create(final SAML2IdPTO idpTO) {
-        return update(saml2EntityFactory.newEntity(SAML2IdP.class), idpTO);
+        return update(entityFactory.newEntity(SAML2IdP.class), idpTO);
     }
 
-    private void populateMapping(
+    private void populateItems(
             final SAML2IdPTO idpTO,
             final SAML2IdP idp,
             final AnyTypeClassTO allowedSchemas) {
@@ -87,7 +83,7 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
         SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
                 ClientExceptionType.RequiredValuesMissing);
 
-        for (ItemTO itemTO : idpTO.getMappingItems()) {
+        for (ItemTO itemTO : idpTO.getItems()) {
             if (itemTO == null) {
                 LOG.error("Null {}", ItemTO.class.getSimpleName());
                 invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
@@ -133,8 +129,9 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
                             scce.addException(invalidMandatoryCondition);
                         }
 
-                        MappingItem item = entityFactory.newEntity(MappingItem.class);
-                        BeanUtils.copyProperties(itemTO, item, MAPPINGITEM_IGNORE_PROPERTIES);
+                        SAML2IdPItem item = entityFactory.newEntity(SAML2IdPItem.class);
+                        BeanUtils.copyProperties(itemTO, item, ITEM_IGNORE_PROPERTIES);
+                        item.setIdP(idp);
                         item.setPurpose(MappingPurpose.NONE);
                         if (item.isConnObjectKey()) {
                             if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) {
@@ -174,7 +171,7 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
         idp.setUseDeflateEncoding(idpTO.isUseDeflateEncoding());
         idp.setBindingType(idpTO.getBindingType());
 
-        idp.getMappingItems().clear();
+        idp.getItems().clear();
         AnyTypeClassTO allowedSchemas = new AnyTypeClassTO();
         for (AnyTypeClass anyTypeClass : anyTypeDAO.findUser().getClasses()) {
             allowedSchemas.getPlainSchemas().addAll(
@@ -187,16 +184,16 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
                     CollectionUtils.collect(anyTypeClass.getVirSchemas(),
                             EntityUtils.<VirSchema>keyTransformer()));
         }
-        populateMapping(idpTO, idp, allowedSchemas);
+        populateItems(idpTO, idp, allowedSchemas);
 
         return saml2IdPDAO.save(idp);
     }
 
-    private void populateMappingTO(final SAML2IdP idp, final SAML2IdPTO idpTO) {
-        for (MappingItem item : idp.getMappingItems()) {
+    private void populateItems(final SAML2IdP idp, final SAML2IdPTO idpTO) {
+        for (SAML2IdPItem item : idp.getItems()) {
             ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
-            BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+            BeanUtils.copyProperties(item, itemTO, ITEM_IGNORE_PROPERTIES);
             itemTO.setPurpose(MappingPurpose.NONE);
 
             if (itemTO.isConnObjectKey()) {
@@ -218,7 +215,7 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
         idpTO.setBindingType(idp.getBindingType());
         idpTO.setMetadata(Base64.encode(idp.getMetadata()));
 
-        populateMappingTO(idp, idpTO);
+        populateItems(idp, idpTO);
 
         return idpTO;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d685eda8/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index 2df4530..fd34bbf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -141,12 +141,12 @@ public class SAML2ITCase extends AbstractITCase {
 
         SAML2IdPTO ssoCircle = ssoCircleOpt.get();
         assertNotNull(ssoCircle);
-        assertFalse(ssoCircle.getMappingItems().isEmpty());
+        assertFalse(ssoCircle.getItems().isEmpty());
         assertNotNull(ssoCircle.getConnObjectKeyItem());
         assertNotEquals("email", ssoCircle.getConnObjectKeyItem().getIntAttrName());
         assertNotEquals("EmailAddress", ssoCircle.getConnObjectKeyItem().getExtAttrName());
 
-        ssoCircle.getMappingItems().clear();
+        ssoCircle.getItems().clear();
 
         ItemTO keyMapping = new ItemTO();
         keyMapping.setIntAttrName("email");