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

  1. 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 and uid=bjensen,ou=People,dc=example,dc=com are also imported with the Example.ldif file.

  2. 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:

  1. 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.

  2. 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"
        }
      ],
      ...
    }
  3. 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"]
  4. Update John Doe's ldapGroups property, to change his membership from the openidm group to the openidm2 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.

  5. 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": []
        }
      ],
      ...
    }
  1. Log in to the Admin UI.

  2. 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.

  3. 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.

  4. To view the new users in the repository, from the navigation bar, click Manage > User.

    IDM displays the two users.

  5. From the Users List page, click the user jdoe.

  6. 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

  7. Update John Doe's ldapGroups property to change his membership from the openidm group to the openidm2 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.

  8. To verify the change: reload John Doe's user information, selecting Linked Systems, and examining the value of his ldapGroups property.

    1. Reload John Doe's user information page.

    2. Click the Linked Systems tab.

      Observe the value of his ldapGroups property.

Read a different version of :