Synchronize LDAP Group Membership
This sample demonstrates synchronization between an LDAP directory and an IDM repository, with a focus on synchronizing LDAP group membership, that is, how the value of the ldapGroups
property in a managed user object is mapped to the corresponding user object in LDAP.
The sample has been tested with ForgeRock Directory Services (DS) but should work with any LDAPv3-compliant server. The sample includes mappings from the LDAP server to the IDM repository, and from the IDM repository to the LDAP server. During the reconciliation, memberships are synchronized, in addition to user entries.
Prepare the Sample
Set up DS using
/path/to/openidm/samples/sync-with-ldap-group-membership/data/Example.ldif
.The import file includes a number of LDAP groups, including the following:
dn: ou=Groups,dc=example,dc=com ou: Groups objectClass: organizationalUnit objectClass: top dn: cn=openidm,ou=Groups,dc=example,dc=com uniqueMember: uid=jdoe,ou=People,dc=example,dc=com cn: openidm objectClass: groupOfUniqueNames objectClass: top dn: cn=openidm2,ou=Groups,dc=example,dc=com uniqueMember: uid=bjensen,ou=People,dc=example,dc=com cn: openidm2 objectClass: groupOfUniqueNames objectClass: top
The users with DNs
uid=jdoe,ou=People,dc=example,dc=com
anduid=bjensen,ou=People,dc=example,dc=com
are also imported with theExample.ldif
file.Prepare IDM, and start the server using the sample configuration:
cd /path/to/openidm/ ./startup.sh -p samples/sync-with-ldap-group-membership
Run the Sample
You can work through the sample using the command line or Admin UI:
Reconcile the repository over the REST interface:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ "http://localhost:8080/openidm/recon?_action=recon&mapping=systemLdapAccounts_managedUser&waitForCompletion=true"
{ "_id": "6652c292-5309-40e5-b272-b74d67dd95c9-4", "state": "SUCCESS" }
The reconciliation operation returns a reconciliation run ID and the status of the operation. Reconciliation creates user objects from LDAP in the IDM repository, assigning the new objects random unique IDs.
Retrieve the user IDs from the repository:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/managed/user?_queryFilter=true&_fields=_id"
{ "result": [ { "_id": "1eaca03d-aef7-415a-99d9-bfd3f442ef51", "_rev": "0000000028e4e01e" }, { "_id": "4e15c41e-6051-4150-8cde-b91c16397f25", "_rev": "00000000bb39e698" } ], ... }
To retrieve individual user objects, include the ID in the URL. The following request retrieves the user object for John Doe:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/managed/user/1eaca03d-aef7-415a-99d9-bfd3f442ef51"
{ "_id": "1eaca03d-aef7-415a-99d9-bfd3f442ef51", "_rev": "0000000028e4e01e", "displayName": "John Doe", "description": "Created for OpenIDM", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "1-415-599-1100", "sn": "Doe", "userName": "jdoe", "ldapGroups": [ "cn=openidm,ou=Groups,dc=example,dc=com" ], "accountStatus": "active", ... }
Note
John Doe's user object contains an
ldapGroups
property, whose value shows his groups on the LDAP server:"ldapGroups":["cn=openidm,ou=Groups,dc=example,dc=com"]
Update John Doe's
ldapGroups
property, to change his membership from theopenidm
group to theopenidm2
group:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '[ { "operation": "replace", "field": "/ldapGroups", "value": ["cn=openidm2,ou=Groups,dc=example,dc=com"] } ]' \ "http://localhost:8080/openidm/managed/user/1eaca03d-aef7-415a-99d9-bfd3f442ef51?_action=patch"
{ "displayName": "John Doe", "description": "Created for OpenIDM", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "1-415-599-1100", "sn": "Doe", "userName": "jdoe", "ldapGroups": [ "cn=openidm2,ou=Groups,dc=example,dc=com" ], "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [], "_rev": "00000000d0ebe04c", "_id": "1eaca03d-aef7-415a-99d9-bfd3f442ef51" }
This command changes John Doe's
ldapGroups
property in the IDM repository, from"cn=openidm,ou=Groups,dc=example,dc=com"
to"cn=openidm2,ou=Groups,dc=example,dc=com"
. Because of implicit synchronization, the change is propagated to the LDAP server. John Doe is removed from the first LDAP group and added to the second LDAP group in DS.To verify the change, query John Doe's record on the LDAP server:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/system/ldap/account/?_queryFilter=uid+eq+'jdoe'"
{ "result": [ { "_id": "0da50512-79bb-3461-bd04-241ee4c785bf", "employeeType": [], "objectClass": [ "person", "organizationalPerson", "inetOrgPerson", "top" ], "cn": "John Doe", "uid": "jdoe", "ldapGroups": [ "cn=openidm2,ou=Groups,dc=example,dc=com" ], "givenName": "John", "mail": "jdoe@example.com", "aliasList": [], "dn": "uid=jdoe,ou=People,dc=example,dc=com", "sn": "Doe", "description": "Created for OpenIDM", "telephoneNumber": "1-415-599-1100", "kbaInfo": [] } ], ... }
Log in to the Admin UI.
From the navigation bar, click Configure > Mappings.
The Mappings page displays two configured mappings, one from the LDAP server to the IDM repository (
managed/user
) and one from the IDM repository to the LDAP server.Select the LDAP to managed user mapping, and click Reconcile.
The reconciliation operation creates the two users from the LDAP server in the IDM repository.
To view the new users in the repository, from the navigation bar, click Manage > User.
IDM displays the two users.
From the Users List page, click the user
jdoe
.Click the Linked Systems tab.
IDM displays John Doe's mapped external resource,
ldap/account
.In the mapped resource, IDM displays John Doe's
ldapGroups
:cn=openidm,ou=Groups,dc=example,dc=com
Update John Doe's
ldapGroups
property to change his membership from theopenidm
group to theopenidm2
group. You must perform this operation over the REST interface:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '[ { "operation": "replace", "field": "/ldapGroups", "value": ["cn=openidm2,ou=Groups,dc=example,dc=com"] } ]' \ "http://localhost:8080/openidm/managed/user?_action=patch&_queryId=for-userName&uid=jdoe"
{ "displayName": "John Doe", "description": "Created for OpenIDM", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "1-415-599-1100", "sn": "Doe", "userName": "jdoe", "ldapGroups": [ "cn=openidm2,ou=Groups,dc=example,dc=com" ], "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [], "_rev": "0000000050c62938", "_id": "8462fe0c-2ab2-459a-a25e-474474889c9e" }
This command changes John Doe's
ldapGroups
property in the IDM repository, from"cn=openidm,ou=Groups,dc=example,dc=com"
to"cn=openidm2,ou=Groups,dc=example,dc=com"
. As a result of implicit synchronization, the change is propagated to the LDAP server. John Doe is removed from the first LDAP group and added to the second LDAP group in DS.To verify the change: reload John Doe's user information, selecting Linked Systems, and examining the value of his
ldapGroups
property.Reload John Doe's user information page.
Click the Linked Systems tab.
Observe the value of his
ldapGroups
property.