In the Quick start, you see the children of /platform and /organization groups are mapped to LDAP, like:
dn: cn=administrators,ou=Platform,o=portal,o=gatein,dc=example,dc=com dn: cn=users,ou=Platform,o=portal,o=gatein,dc=example,dc=com dn: cn=guests,ou=Platform,o=portal,o=gatein,dc=example,dc=com dn: cn=web-contributors,ou=Platform,o=portal,o=gatein,dc=example,dc=com
That is corresponding to the configuration:
The readOnly option is set to false.
You have mapped Platform groups with group types:
/platform/*) with platform_type.
/organization/* with organization_type.
There are some facts about this group mapping:
The mapping is done for the child groups, not for the configured group itself.
As a result, if you want /platform to be created as a group entry in LDAP, you need to configure the root group (/). Thus, the /organization (child of root) will be mapped too. There is no filter for this mapping.
The wildcard (*) indicates that children at all levels will be mapped. Without it, only the children at level one are mapped.
The hierarchical groups are turned into flat in group mapping. To be clear, if the /platform/users group has a child like /platform/users/intranet, the parent-child relationship is lost in translation into LDAP (although cn=intranet might be listed as member in cn=users):
dn: cn=users,o=platform,o=acme,dc=my-domain,dc=com dn: cn=intranet,o=platform,o=acme,dc=my-domain,dc=com
As a result, it will prevent you from creating /platform/administrators/intranet if /platform/users/intranet already exists.
Because of the difference between Organization Models, there is no way to store membership and membership type in LDAP exactly like the presentation of concepts in eXo Platform. See details later in the explanation of associationMembershipType option.
In this tutorial, you will write your own group type mapping, however it uses the mapping between /platform/* and platform_type as example so the configuration sample is the same to the Quick start.
Besides, the configuration is common for LDAP-to-Platform and Platform-to-LDAP mapping
(PicketLink IDM framework does not distinguish between them), but the effect of some parameters is different, so you need to read carefully
even if you already read the LDAP-to-Platform mapping. For example, the createEntryAttributeValues
parameter
has no effect on the LDAP-to-Platform mapping.
Create your group type.
In idm-configuration.xml
, the Platform parent group needs to be matched with your group type and be declared
in the ignoreMappedMembershipTypeGroupList field:
<component>
<key>org.exoplatform.services.organization.OrganizationService</key>
<type>org.exoplatform.services.organization.idm.PicketLinkIDMOrganizationServiceImpl</type>
...
<field name="groupTypeMappings">
<map type="java.util.HashMap">
..
<entry>
<key><string>/platform/*</string></key>
<value><string>platform_type</string></value>
</entry>
</map>
</field>
...
<field name="ignoreMappedMembershipTypeGroupList">
<collection type="java.util.ArrayList" item-type="java.lang.String">
<value><string>/platform/*</string></value>
...
</collection>
</field>
...
</component>
Configure the associationMembershipType field.
<field name="associationMembershipType">
<string>member</string>
</field>
In the Platform-to-LDAP mapping, it indicates which membership type can be stored in LDAP, or more exactly, which membership creation can trigger writing an "member" attribute in LDAP.
For example, in eXo Platform, you add the root user to the /platform/users group with the membership type as manager. This membership (manager:/platform/users) is not stored in LDAP. Next you continue to add root to /platform/users, but with membership type as member. The type is configured for associationMembershipType, so this time an attribute is added to the group entry like this:
dn: cn=users,o=platform,o=acme,dc=my-domain,dc=com ... member: uid=root,ou=People,o=acme,dc=my-domain,dc=com
As said before, this attribute marks that root belongs to the group, but does not tell which membership type he has. The attribute name here is "member" because the parentMembershipAttributeName option is set to member that is not corresponding to associationMembershipType.
Some values you can configure for associationMembershipType are *, member, manager, author, editor. Those membership types are predefined in the eXo Platform configuration but can be re-configured or changed via UI, so you need to check them again. Note that the asterisk (*) is treated like other types.
In picketlink-idm-ldap-config.xml
, the group type is declared under the identity store PortalLDAPStore.
First write a few lines for the schema of the group type, then fill up attributes and options later:
<identity-store>
<id>PortalLDAPStore</id>
...
<supported-identity-object-types>
<identity-object-type>
<name>platform_type</name>
<relationships>
<relationship>
<relationship-type-ref>JBOSS_IDENTITY_MEMBERSHIP</relationship-type-ref>
<identity-object-type-ref>USER</identity-object-type-ref>
</relationship>
<relationship>
<relationship-type-ref>JBOSS_IDENTITY_MEMBERSHIP</relationship-type-ref>
<identity-object-type-ref>platform_type</identity-object-type-ref>
</relationship>
</relationships>
<credentials/>
<attributes>
</attributes>
<options>
</options>
</identity-object-type>
</supported-identity-object-types>
</identity-store>
The group type needs to be referenced by the PortalRepository repository:
<repository>
<id>PortalRepository</id>
...
<identity-store-mapping>
<identity-store-id>PortalLDAPStore</identity-store-id>
<identity-object-types>
...
<identity-object-type>platform_type</identity-object-type>
...
</identity-object-types>
</identity-store-mapping>
...
</repository>
Add the attributes mapping.
The Platform group "id" is groupName. Its mapping is definitive and is configured by options, not attributes. The other attributes are label and description, both are not mandatory. You can map them to cn and description LDAP attributes.
<identity-object-type>
<name>platform_type</name>
...
<attributes>
<attribute>
<name>label</name>
<mapping>cn</mapping>
<type>text</type>
<isRequired>false</isRequired>
<isMultivalued>false</isMultivalued>
<isReadOnly>true</isReadOnly>
</attribute>
<attribute>
<name>description</name>
<mapping>description</mapping>
<type>text</type>
<isRequired>false</isRequired>
<isMultivalued>false</isMultivalued>
<isReadOnly>false</isReadOnly>
</attribute>
</attributes>
</identity-object-type>
Add options.
You need to configure the LDAP attribute that matches to group id (groupName in eXo Platform). Traditionally, it is cn:
<option>
<name>idAttributeName</name>
<value>cn</value>
</option>
The ctxDNs (context DNs) indicates the parent entry under which the groups are created. If the parent entry does not exist, it will be created automatically. Although the option accepts multiple values, only the first value is used in the Platform-to-LDAP mapping.
<option>
<name>ctxDNs</name>
<value>o=platform,o=acme,dc=example,dc=com</value>
</option>
In OpenLDAP or MSAD default schemas, the "member" attribute is used to list the dn of the members. However, your schema may use another attribute, so it should be configurable:
<option>
<name>parentMembershipAttributeName</name>
<value>member</value>
</option>
Required by LDAP, a group entry should have fixed objectClasses and attributes that could not be mapped from the eXo Platform group attributes. You can provide such objectClasses/attributes in createEntryAttributeValues like below:
<option>
<name>createEntryAttributeValues</name>
<value>objectClass=top</value>
<value>objectClass=groupOfNames</value>
</option>
The samples of this option are different between OpenLDAP/MSAD and others, so you need to review it in the sample configuration file you are using.
Particularly in OpenLDAP, the member is a MUST attribute to groupOfNames, so a placeholder is used (to be added as a member) to satisfy the rule:
<option>
<name>parentMembershipAttributePlaceholder</name>
<value>ou=placeholder,o=platform,o=acme,dc=my-domain,dc=com</value>
</option>
...
<option>
<name>createEntryAttributeValues</name>
...
<value>member=ou=placeholder,o=platform,o=acme,dc=my-domain,dc=com</value>
</option>