LDAP Login Integration

A LDAP directory may serve as a source of users and/or groups of the Relution server. Once set up, accounts known to LDAP can be used straight to log in to Relution. Also, it’s possible to use a LDAP directory for account management only.

Notice that using a LDAP or ActiveDirectory is optional. Relution comes with a local users and groups management that can be used standalone instead.

Overview

Relution is able to synchronize all LDAP users and groups into Relution, that are configured in the LDAP configuration. Groups are defined by the attributes in the section Group Mapping. Users are defined by the attributes in the User Mapping section. During the login process of a user, the users data will be synchronized into Relution. The synchronization requests to the LDAP server are minimized by Relution, so that only the login process requires a synchronization. All other accesses during runtime are executed against the Relution’s database. Obviously, the users passwords are not synchronized and are not stored in the Relution database.

Configuration

The configuration of the LDAP connection needs to be added to the <INSTALL_DIR>/application.yml. This is a YAML file, so whitespace is important. The ldap key is on the root level (same as relution) and each level of subkey is indented with two spaces (no tabs!)

ldap:
  default:
    # Name of the LDAP configuration
    name: LDAP Configuration

    # UUID —or— unique name of the Relution organization to import into
    organizationUuid: # uuid
    organizationUniqueName: # unique_name

    # URL(s) of the LDAP server(s) to import from
    ldapUrls:
      - '<LDAP_URL_1>'
      - '<LDAP_URL_2>'
      - …

    # Credentials of the account used to connect to the LDAP server(s)
    ldapUserDn: # Distinguished Name (DN) of the user account
    _ldapPassword: # Password

    # Base domain components and organizational units to search
    ldapBase: 'OU=AADDC,DC=mwaysolutions,DC=com'
    ldapReferral: ignore
    ldapPoolSize: 2

    # User mapping
    userSearchBase: # OU that contains the users to import, relative to ldap_base
    userSearchFilterTemplate: '(&(cn=%v)(objectClass=person))'

    # Search scope options:
    # 0 = Object
    # 1 = One Level
    # 2 = Subtree
    userSearchScope: 2

    # Sync interval options: 1h, 2h, 4h, 8h, 12h, 24h, 48h, 168h
    syncUsers: false
    syncUsersOnStartup: true
    syncUsersInterval: 24h
    syncUsersSchedule:

    # The action to take when a previously synchronized
    # user is no longer returned by the provider
    # default: none
    # We STRONGLY recommend to read the glossary before changing this option
    syncUsersActionWhenMissing: none | disable | delete

    # Manual user attribute mapping
    # Enable manual user attribute mapping
    manualUserMapping: false
    userAttributeForeignKey: # ldap attribute name
    userAttributeName:
    userAttributeSalutation:
    userAttributeGivenName:
    userAttributeSurname:
    userAttributePosition:
    userAttributeEmail:
    userAttributePhone:
    userAttributeCountry:
    userAttributeLocked:
    userAttributeCustom1:
    userAttributeCustom2:
    userAttributeCustom3:
    userAttributeCustom4:
    userAttributeCustom5:
    userAttributeCustom6:
    userAttributeCustom7:
    userAttributeCustom8:
    userAttributeCustom9:
    userAttributeCustom10:

    # Group mapping
    groupSyntheticGroup: 'LDAP_Users'
    groupUseGroups: true
    groupSearchBase: # OU that contains the groups to import, relative to ldap_base
    groupSearchFilterTemplate: '(&(cn=%v)(objectClass=groupofnames))'

    # Search scope options:
    # 0 = Object
    # 1 = One Level
    # 2 = Subtree
    groupSearchScope: 2

    # Sync interval options: 1h, 2h, 4h, 8h, 12h, 24h, 48h, 168h
    syncGroups: true
    syncGroupsOnStartup: true
    syncGroupsInterval: 24h
    syncGroupsSchedule:

    # Manual group attribute mapping
    # Enable manual group attribute mapping
    manualGroupMapping: false
    groupAttributeForeignKey: # ldap attribute name
    groupAttributeName:
    groupAttributeMember:

    # Additional synthetic groups
    'syntheticGroup_<Group Name 1>': (&(cn=<common-name>)(objectClass=<class>))
    'syntheticGroup_<Group Name 2>': (&(cn=<common-name>)(objectClass=<class>))

    # Synthetic group to role mapping
    groupRolesJson: |
      {
        "<Group Name 1>": ["<Role 1>", "<Role 2>", …],
        "<Group Name 2>": ["<Role 3>", "<Role 4>", …],
        …
      }

    # Assign users to different organizations based on LDAP properties
    organizationUserFilters:
      - <orgUniqueName>=<LDAP-filter-expression>
      - <orgUniqueName>=dn=<expression>
      - …

    # Assign groups to different organizations based on LDAP properties
    organizationGroupFilters:
      - <orgUniqueName>=<LDAP-filter-expression>
      - <orgUniqueName>=dn=<expression>
      - …

A configuration in Relution consists of the parts

  • Connection to LDAP server:

    • ldapUrls of your LDAP server(s) (including the protocol and port)

      e.g.
          - ldap://192.168.128.195:389
      
          —or—
      
          - ldaps://ldap.myorga.com:636

      Specifying a port is optional if the default port for the protocol is used.

    • Enterprise user account (ldapUserDn, _ldapPassword) incl. credentials for read-only access

      (user account and password can be left unset when using an LDAP server without authentication)

    • ldapBase

      The base DN is the distinguished name of the node which all operations are relative to.

  • Organization mapping:

    Currently a single configuration can map users and groups to one organization only. The organization picked needs to be created before configuring LDAP. In case LDAP and Kerberos are used in combination, make sure to use the Realm name as Relution’s organisation unique name!

  • User mapping:

    The User Mapping attributes in this configuration map the user nodes from the LDAP server to Relution users and their attributes.

  • Group mapping:

    Defines which nodes and attributes from the LDAP server are mapped to the Relution groups. Extraction of groups is optional and needs to be used only if you intent to grant differing permissions on the Relution middleware depending on LDAP groups. Regardless of your choice, there is one group created that all LDAP users (and groups) are a member of implicitly, called the synthetic group.

User mapping

To import users in general:

  1. Enter a userSearchFilterTemplate to select which nodes of the LDAP are users.

    In most cases the following LDAP filter expression can be used:

    (&(cn=%v)(objectClass=person))

    The placeholder %v is replaced with the search term (“value”) entered in the search dialog, when searching for LDAP users.

  2. For userSearchScope, in case of a hierarchical LDAP tree choose the Subtree option, which results in the system to run queries on all child nodes down a hierarchy. In such a setup, users are stored under groups which eventually are nested in other groups. Flat environments (e.g. Microsofts Active Directory) should choose “One Level” as User Search Scope.

  3. User Search Base

    The node (DN) under which all users are stored in the LDAP is a combination of Base DN and the appended Search Base.

    Example:
    • base dn: dc=mwaysolutions,dc=com

    • user search base: ou=users

    • users will be searched in: ou=users,dc=mwaysolutions,dc=com

Group mapping

Mapping groups works much the same way as for users. However, in many usage scenarios there is no need of mapping groups. When a single group suffices for managing permissions then it’s enough to set groupSyntheticGroup to the name of the synthetic group. The synthetic group is the one which all LDAP users are a member of implicitly. That group is created automatically by the system. For configuration just enter a group name for it.

In case LDAP groups should be mapped as well:

  1. The groupUseGroups options must set to true.

  2. Enter a groupSearchFilterTemplate selecting the LDAP group nodes.

    A typical filter expression is: (&(cn=%v)(objectClass=group))

    The placeholder %v is replaced with the search term (“value”) entered in the search dialog, when searching for LDAP groups.

  3. The groupSearchScope is likely the same setting as for users. Likewise a groupSearchBase may optionally be given.

Notice, at the time of writing there is no support for forming group memberships based on a user’s memberOf attribute. This means, group members must be defined by some member attribute on the group side. Some systems, like OpenLDAP, give administrators the choice, while others like ActiveDirectory support both directions at the same time.

User synchronization

Where groups are synchronized automatically after configuring your LDAP directory in Relution (if group mapping is enabled), the users are only synchronized individually after their first login or after a device-enrollment for an user by default. To enforce the synchronization of all users (all users under the LDAP node specified in user mapping above) set the syncUsers option to true. Enabling this, you can additionally specify a syncUsersInterval at which synchronization should be performed.

Advanced Configuration

ACL Settings

Default ACLs may be given explicitly. When applied, the settings will be used for LDAP user and group and for synthetic group creations. The Relution Server will make sure that users and groups can at least read themselves. Notice however, in most cases it is preferable to using ACL template rules by keeping the ACLs unset.

Administration

Once configured, account management is primarily done in the LDAP directory. That is users and/or groups are created and managed therein. However, some orchestration remains to be done on the Relution Server itself. Here system level permissions are granted to LDAP users indirectly. This works by assigning system roles to individual LDAP groups, or to the synthetic group of all users originating from an LDAP directory. To do so, please use the group management facilities of the Relution Server just as for legacy accounts.

Usage examples

The following sections show some typical usage examples with a more in depth explanation for the most commonly used configuration options.

LDAP servers

To configure an LDAP server, specify the server’s scheme, host name or IP address and its port. The scheme and port depends on whether LDAP or secure LDAP (LDAPS) is used.

    # LDAP without encryption
    ldapUrls:
      - ldap://ldap01.example.org:389

    # LDAP with encryption
    ldapUrls:
      - ldaps://ldap01.example.org:636

To configure more than one LDAP server, multiple URLs can be specified as a YAML sequence (or array).

    ldapUrls:
      - ldaps://ldap01.example.org:636
      - ldaps://ldap02.example.org:636
      - ldaps://ldap03.example.org:636

For security reasons LDAPS is recommended.

LDAP credentials

Access to an LDAP server typically requires authentication. For security reasons we recommend to use a separate user account that has read-only permissions. At the very least this account requires permission to read the user accounts and groups to be imported.

    ldapUserDn: cn=relution_import,dc=mwaysolutions,dc=com
    _ldapPassword: <password>

Note that the username must be specified in the form of a distinguished name (DN) that uniquely identifies the account.

Organization to import into

To specify which Relution organization users and groups should be imported into, specify either the organization’s unique identifier (UUID) or the organization’s unique name. Currently only one Relution organization can be associated with an LDAP server.

    organizationUuid: <uuid>
—or—
    organizationUniqueName: <unique name>

Group for all LDAP users

All LDAP users imported into a Relution organization are automatically added as members of the same synthetic group (they can be added to additional groups). The parameter specifies the name of this group. The name is always prefixed with the organization name, e.g. <org> LDAP.

    groupSyntheticGroup: LDAP

Base path

To shorten the DNs that need to be specified for search paths, the common ancestor can be specified as ldapBase.

    ldapBase: OU=AADDC,DC=mwaysolutions,DC=com

The base above specifies the Domain Component (DC) com and mwaysolutions and the Organizational Unit (OU) AADDC. This represents the following LDAP tree:

Base path

Search base

The search base specifies the Organizational Unit (OU) that holds the users or groups to be imported. The search base is relative to the LDAP base specified above.

    userSearchBase: OU=South,OU=People
    groupSearchBase: OU=South,OU=Groups

In this case the import would include users that are child nodes of the following directory tree:

Search base users

Likewise it would include groups that are child nodes of the following directory tree:

Search base groups

To import users and groups recursively, the search scope needs to be set to 2. If the search scope is set to 1 only direct child nodes are included.

    userSearchScope: 2
    groupSearchScope: 2

Example: If search scope is set to 1, the search base defined above would only include the users Jane Doe and John Doe from the directory tree shown below. If search scope is set to 2 the user Jill Doe is included as well.

Search base user scope

Search filter

To allow for more fine grained control over which users and groups are imported, an additional filter can be specified.

    userSearchFilterTemplate: '(&(cn=%v)(objectClass=person))'
    groupSearchFilterTemplate: '(&(cn=%v)(objectClass=groupOfNames))'

With the filters above, a user account is only imported if it has the object class person and a group is only imported if it has the object class groupOfNames. This can be used in addition to the search base, which limits the organizational units from which users and groups are imported. Note that object classes can vary depending on which LDAP server is used.

As described above, the placeholder %v is replaced with the search term (“value”) entered in search dialogs, when searching for LDAP users or groups. This means a manual search filters its results based on an object’s Common Name (CN), while otherwise using the same filter expression as the LDAP import. In all other cases this additional filter has no effect.

It is also possible to filter users based on their group membership.

    userSearchFilterTemplate: '(&(&(cn=%v)(objectClass=person))(memberOf=CN=example_group,OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com))'

In the example above, users need to have the object class person and must be members of a group with the Common Name (CN) example_group, which is part of the organizational unit South.Groups.AADDC and the domain mwaysolutions.com. Note that the property for group membership (e.g. memberOf) can vary depending on which LDAP server is used. A manual search once again filters its results based on the object’s Common Name (CN).

Additional groups

It’s possible to create additional synthetic groups and add users to these groups based on LDAP filters.

     'syntheticGroup_LDAP Administrators': (&(cn=admin_staff)(objectClass=Group))
     'syntheticGroup_LDAP Users': (&(cn=dev_team)(objectClass=Group))

The two keys above create the synthetic groups LDAP Administrators and LDAP Users in the Relution organization. Imported users that are members of the LDAP group admin_staff are added to the Relution group LDAP Administrators and users that are members of the LDAP group dev_team are added tot he Relution group LDAP Users.

As noted above, all imported LDAP users are also always added to the <org> LDAP group.

Group to roles mapping

To automatically map synthetic groups to built-in Relution groups (known as roles) it is possible the specify a mapping.

    groupRolesJson: |
      {
        "LDAP Administrators": ["%o Administrator"],
        "LDAP Users": ["%o Appstore User", "%o Device User"]
      }

This will add the synthetic group LDAP Administrators to the role <org> Administrator. This means any user who’s a member of this synthetic group will have the administrator role in Relution. In combination with the group definition from the previous example, any user who’s a member of the LDAP group admin_staff and is imported into Relution receives administrative permissions in Relution.

The synthetic group LDAP Users is added to the roles <org> Appstore User and <org> Device User. This means any user who’s a member of this synthetic group will have permission to see the app store and enroll their device into Relution. In combination with the group definition from the previous example, any user who’s a member of the LDAP group dev_team can sign into Relution and access its app store.

User to organization mapping

To map users to different organizations based on their LDAP attributes, it is possible to specify organization user filters.

    organizationUserFilters:
      - <orgUniqueName_A>=<LDAP-filter-expression>
      - <orgUniqueName_B>=dn=<expression>

These filters can be used to assign users to different organizations based on their attributes or a partial match of their distinguished name (DN). It is possible to define multiple such filters.

The <LDAP-filter-expression> can be replaced by any LDAP filter expression. Users whose attributes match this LDAP filter expression are assigned to the organization identified by <orgUniqueName_A>.

For example the LDAP filter expression (memberOf=CN=example_group,OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com) assigns users who are a member of example_group to the organization with the unique name orgUniqueName_A. Users who do not match this expression are assigned to the default organization identified by organizationUuid or organizationUniqueName unless they match another organization user filter.

The <expression> can be replaced with a partial distinguished name (DN). Users whose distinguished name matches this expression are assigned to the organization identified by <orgUniqueName_B>.

For example the expression *OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com assigns users whose DN ends with OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com to the organization identified by <orgUniqueName_B>. The wildcard character * can be used at the start, end or both to match a DN that ends with, starts with or contains the specified expression.

Group to organization mapping

To map groups to different organizations based on their LDAP attributes, it is possible to specify organization group filters.

    organizationGroupFilters:
      - <orgUniqueName_A>=<LDAP-filter-expression>
      - <orgUniqueName_B>=dn=<expression>

These filters can be used to assign groups to different organizations based on their attributes or a partial match of their distinguished name (DN). It is possible to define multiple such filters.

The <LDAP-filter-expression> can be replaced by any LDAP filter expression. Groups whose attributes match this LDAP filter expression are assigned to the organization identified by <orgUniqueName_A>.

For example the LDAP filter expression (memberOf=CN=example_group,OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com) assigns groups who are a member of example_group to the organization with the unique name orgUniqueName_A. Groups who do not match this expression are assigned to the default organization identified by organizationUuid or organizationUniqueName unless they match another organization group filter.

The <expression> can be replaced with a partial distinguished name (DN). Groups whose distinguished name matches this expression are assigned to the organization identified by <orgUniqueName_B>.

For example the expression *OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com assigns groups whose DN ends with OU=South,OU=Groups,OU=AADDC,DC=mwaysolutions,DC=com to the organization identified by <orgUniqueName_B>. The wildcard character * can be used at the start, end or both to match a DN that ends with, starts with or contains the specified expression.

Synchronization interval

The synchronization interval specifies how often users and groups are imported into Relution. If the interval is set to 24 hours (as shown below) it will take up to a day before changes to the LDAP system will be available in Relution.

    syncUsersInterval: 24h
    syncGroupsInterval: 24h

If the number of users to be imported is very large (>1,000) it is generally recommended to disable periodic synchronization.

    syncUsers: false

In this case a user account is imported on demand, i.e. whenever the user signs in.

Synchronization schedule

Since server version 5.7 it is now also possible to schedule synchronization using Cron syntax. If both an interval and a schedule are specified, the schedule takes precedence (i.e. the interval is ignored).

    syncUsersSchedule: '0 0 0 */1 * *'
    syncGroupsSchedule: '0 0 0 */1 * *'

The example above specifies that user and group synchronization should happen once a day at midnight (local time). Note that non-standard Cron syntax like @hourly, @daily and @weekly is also supported.

Manual mapping

If the default mapping of user attributes doesn’t work as expected or you want to map specific attributes it’s possible to specify a custom mapping.

    manualUserMapping: true
    userAttributePhone: mobile

The example above maps the user’s mobile phone number (in LDAP) to the user’s phone number (in Relution). By default the system would map the user’s landline to Relution’s phone number field. Note that manualUserMapping needs to be set to true to enable this functionality.

There’s an additional ten custom attributes in Relution that can be used to import arbitrary LDAP properties, should you need them.

    userAttributeCustom1: some_ldap_attribute_01
    …
    userAttributeCustom10: some_ldap_attribute_10

Import classes from LDAP

Relution’s LDAP import can be configured to create education classes based on LDAP groups. The members these groups are assigned as teachers or students of the classes.

The use of this feature requires the Education license, which is only available to educational institutions.

A user is assigned as a teacher, if it is a member of the group and matches the appropriate search filter for teachers. A user is assigned as a student, if it is a member of the group and matches the appropriate search filter for students and has not already been assigned as a teacher. A user who matches both filters is assigned as a teacher.

A class is only created, if it has at least one teacher and at least one student. If a user has not already been synchronized, the user is imported without any of its roles for performance reasons. In this case the user is assigned to the system group "$ORG DEVICE USER" to be able to assigned to an enrollment. Starting with version 4.52, teachers are also automatically assigned to the "$ORG TEACHER" system group.

Example configuration:

ldap:
  default:
  <...>
    syncEduObjects: true
    syncEduOnStartup: true
    syncEduInterval: 1h
    syncEduSchedule:

    # Classes
    eduClassSearchBase: # OU that contains classes, relative to ldapBase
    eduClassSearchScope: 2
    eduClassSearchFilterTemplate: (objectClass=group)

    # Teachers
    eduTeacherSearchBase: # OU that contains teachers, relative to ldapBase
    eduTeacherSearchScope: 1
    eduTeacherSearchFilterTemplate: (&(objectClass=person)(memberOf=CN=...))
    eduTeacherDisableDefaultSystemGroupAssignment: false

    # Students
    eduStudentSearchBase: # OU that contains students, relative to ldapBase
    eduStudentSearchScope: 1
    eduStudentSearchFilterTemplate: (objectClass=person)

Sync education objects

The key syncEduObjects specifies whether LDAP import should create education classes and assign teachers and students.

If syncEduObjects is set to true, the import creates classes based on the LDAP structure. It assigns the group’s members as teachers and students based on their LDAP attributes. If set to false (default), this functionality is disabled.

Sync education interval

The key syncEduInterval specifies how often education objects are synchronized. The interval is ignored, if a schedule is specified.

Sync education schedule

The key syncEduSchedule specifies how often education objects are synchronized, using Cron syntax. If both an interval and a schedule are specifed, the interval is ignored.

Since: Relution Server 5.7

Sync education on startup

The key syncEduOnStartup specifies whether course, teacher and student synchronization should run for the first time after the server completes startup.

If syncEduInterval is used, this value defaults to true. Synchronization is run after the server has started and repeats periodically at the specified interval, unless this parameter is explicitly set to false. If set to false, initial synchronization is run for the first time after the specified interval has elapsed after server startup.

If syncEduSchedule is used, this value defaults to false. Synchronization is only run at the specified schedule, unless this parameter is explicitly set to true. If set to true, synchronization is also run once after server startup, before the schedule takes effect.

Since: Relution Server 5.7

Search base for classes

The key eduClassSearchBase specifies the base LDAP object to search when creating classes. The search base is relative to the ldapBase.

Groups that are hierarchically below the search base are possible candidates to be imported as an education class. A group is imported as a class, if it is within the search scope, matches the search filter and has at least one teacher and student.

Search scope for classes

The key eduClassSearchScope specifies whether import of classes searches the base (0), one-level (1) or subtree (2).

If set to "base" (0), the group that is specified by the search base is imported as a class, if it matches the search filter and has at least one teacher and student.

If set to "one-level" (1), any group that is an immediate child of the base object specified by the search base is imported as a class, if it matches the search filter and has at least one teacher and student. The base object itself is excluded.

If set to subtree (2), any child object as well as the base object itself are imported as classes, if they match the search filter and have at least one teacher and student.

Search template for classes

The key eduClassSearchFilterTemplate specifies the filter a group must match to be imported as a class. A group that is part of the search scope is imported as a class, if it matches this filter and has at least one teacher and student.

Search base for teachers

The key eduTeacherSearchBase specifies the base object to search for users to assign as teachers of classes. The search base is relative to the ldapBase.

Users that are hierarchically below the search base are possible candidates to be imported as teachers. Whether a user is imported as a teacher depends on the search scope and search filter.

Search scope for teachers

The key eduTeacherSearchScope specifies whether import of teachers searches the base (0), one-level (1) or subtree (2).

If set to "base" (0), the user that is specified by the search base is imported as a teacher, if it also matches the search filter and is a member of at least one class. This means at most a single user is imported as a teacher.

If set to "one-level" (1), any user that is an immediate child of the base object specified by the search base is imported as a teacher, if it also matches the search filter. The base object is excluded.

If set to subtree (2), any child object as well as the base object itself are imported as teachers, if they also match the search filter.

Search template for teachers

The key eduTeacherSearchFilterTemplate specifies the filter a user must match to be assigned as a teacher of one or more classes. Any user that matches this filter is assigned as a teacher of the class(es) they are a member of.

Disable default teacher group assignment

The key eduTeacherDisableDefaultSystemGroupAssignment can be used to disable the default group assignment for teachers. If the key is not specified or is set to false, teachers are assigned to the "$ORG TEACHER" system group by default. If this behavior is not desired, the key can be set to true to disable this behavior.

Search base for students

The key eduStudentSearchBase specifies the base object to search for users to assign as students of classes. The search base is relative to the ldapBase.

Users that are hierarchically below the search base are possible candidates to be imported as students. Whether a user is imported as a student depends on the search scope and search filter.

Search scope for students

The key eduStudentSearchScope specifies whether import of students searches the base (0), one-level (1) or subtree (2).

If set to "base" (0), the user that is specified by the search base is imported as a student, if it also matches the search filter. This means at most a single user is imported as a student.

If set to "one-level" (1), any user that is an immediate child of the base object specified by the search base is imported as a student, if it also matches the search filter. The base object is excluded.

If set to subtree (2), any child object as well as the base object itself are imported as a student, if they also match the search filter.

Search template for teachers

The key eduStudentSearchFilterTemplate specifies the filter a user must match to be assigned as a student of one or more classes. Any user that matches this filter is assigned as a student of the class(es) they are a member of.

Group memberships with memberUid

  • Relution version 4.52 or higher

Starting with version 4.25 Relution now also supports LDAP servers that express group memberships with the memberUid attribute. Before, only LDAP servers that used the member attribute were supported. The memberUid attribute uses a member’s uid to express a group membership, while the member attribute uses the distinguished name (DN).

Relution uses code to auto-detect the LDAP server that is used and automatically uses the default group-member attribute for that server type. If an LDAP server deviates from the standard (e.g. iServ), you can use the following configuration to override the automatic mapping:

ldap:
  <key>:
    organizationUniqueName: <org-name>
    <...>
    manualGroupMapping: true
    groupAttributeMember: memberUid

Example iServ configuration

For iServ LDAP servers, the following configuration can be used:

ldap:
  <key>:
    organizationUniqueName: <org-name>
    <...>
    manualGroupMapping: true
    groupAttributeMember: memberUid
    groupAttributeForeignKey: gidNumber

Technically, iServ is an OpenLDAP server. By default OpenLDAP uses the member attribute, which is why Relution defaults to this attribute for group memberships. The above configuration overrides the member attribute to use memberUid instead.

In addition to this, groups in IServ do not have a uid attribute, which means the gidNumber must be used as the foreign key. The remaining attributes follow the standard for OpenLDAP and don’t need to be specified manually.

Troubleshooting

There is more than one existing group/user for filter

There may be cases where a login attempt or a device enrollment results in an error message similar to the one below:

there is more than one existing group for filter AND [foreignKey = '212fd33b-7edc-4dea-acc7-89feae91614b', organizationUuid = '204ED105-1669-4988-9EDC-E5D7F5088B18']

This may be the case if several different LDAP configurations have been executed for the same organization or if the LDAP server has been recreated or migrated.

When Relution synchronizes a user/group with the LDAP server, it also stores the unique key by which the user/group is identified by the LDAP server. If such a unique key for a user/group is changed in the LDAP server (e.g. as part of a migration), Relution is no longer able to uniquely identify the user/group.

The problem can be solved by resetting the information about the LDAP’s unique user/group key. Relution refills this information during the next synchronization and/or user logon.

To reset the information run the following the SQL statement:

UPDATE security_role secrole
SET    secrole.foreign_key = NULL

Glossary

Provider name

    name: <value>

The name of the LDAP configuration. This name is used internally to identify objects imported from this LDAP provider.

This value must not be changed after initial import. Otherwise previously synchronized objects can’t be found and will be imported again.

Organization

    organizationUuid: # uuid
    organizationUniqueName: # unique_name

Identifies the organization imported objects are assigned to. Use either organizationUuid or organizationUniqueName to specify an organization. Only one or the other is required. If both are present, they must identify the same organization.

LDAP URLs

    ldapUrls:
      - '<LDAP_URL_1>'
      - '<LDAP_URL_2>'
      - …

The URL(s) of the LDAP servers to import objects from. It is possible to specify more than one URL, in case of redundant servers.

LDAP credentials

    ldapUserDn:
    _ldapPassword:

The distinguished name (DN) and password of the LDAP user account used by Relution to bind to the configured LDAP server(s).

For security reasons we recommend to use an account with read-only permissions.

The underscore at the start of "ldapPassword" ensures that its value is never shown in the system properties.

LDAP base

    ldapBase: 'OU=AADDC,DC=mwaysolutions,DC=com'

The search base DN for all search operations. All other searches are relative to this DN.

LDAP refferal

    ldapReferral: ignore | follow

Defines how LDAP refferals should be treated. The default value is ignore, which means refferals are not considered when searching the LDAP. When this option is set to follow, refferals are automatically followed.

Note that this might require particular name server setup in order to work (the referred URLs will need to be automatically found using standard DNS resolution).

Since: Relution Server 5.7 - The incorrect spelling "ldapRefferal" has been deprecated and support will be removed in a future version. The server currently accepts both variations. The correct spelling takes precedence.

LDAP pool size

    ldapPoolSize: 20

Sets the maximum number of connections of the built-in LDAP connection pool. Set to 1 to disable connection pooling. The default value is 20.

Synchronize users

    syncUsers: false | true

Determines whether users should be imported periodically or on demand. If set to false (default) Relution connects to the configured LDAP server whenever a user attempts to sign in. If a user is found and their credentials are valid, the user is imported.

If set to true all user objects that match the search criteria are imported periodically.

User synchronization interval

    syncUsersInterval: 24h

Determines how often user objects should be synchronized, if syncUsers is set to true. This value can be specified in either days, hours, minutes or seconds. The lowest possible value is 30 minutes (30m). The default value is 24 hours (24h) which is equal to one day (1d). This value is ignored, if a syncUsersSchedule is defined.

We generally do not recommend to use values lower than one day to ensure concurrent import operations do not overlap, which may result in undefined behavior.

Since: Relution Server 5.7 - The parameter "syncInterval" has been deprecated in favor of "syncUsersInterval" and support will be removed in a future version. The server currently accepts both variations. The new spelling takes precedence.

User synchronization schedule

    syncUsersSchedule: '* * * */1 * *'

Determines how often user objects should be synchronized, if syncUsers is set to true. This value accepts Cron syntax, the non-standard values @hourly, @daily and @weekly are also supported. If syncUsersSchedule is set to a non-empty value, the value of syncUsersInterval is ignored.

If synchronizing a large number of users on a tight schedule, synchronization may repeat immediately after completion. We recommend to use a schedule that is appropriate for the number of objects being imported and the speed of your server(s) and network connection.

Since: Relution Server 5.7

User synchronization on startup

    syncUsersOnStartup: true

The key syncUsersOnStartup specifies whether user synchronization should run for the first time after the server completes startup. If the value is ommited, the default is used.

If syncUsersInterval is used, this value defaults to true. Synchronization is run after the server has started and repeats periodically at the specified interval, unless this parameter is explicitly set to false. If set to false, initial synchronization is run for the first time after the specified interval has elapsed after server startup.

If syncUsersSchedule is used, this value defaults to false. Synchronization is only run at the specified schedule, unless this parameter is explicitly set to true. If set to true, synchronization is also run once after server startup, before the schedule takes effect.

Since: Relution Server 5.7

User search base

    userSearchBase: # OU that contains the users to import, relative to ldapBase

The search base of user objects, relative to the LDAP base. It works in conjunction with the search scope and filter template to define the subtree of entries that should be considered when searching for users to import.

User search scope

    userSearchScope: 2

The search scope to use when searching for user objects.

If set to "base" (0), only the user that is specified by the search base is imported, if it matches the search filter.

If set to "one-level" (1), any user that is an immediate child of the base object specified by the search base is imported, if it matches the search filter. The base object itself is excluded.

If set to subtree (2), any child object as well as the base object itself are imported as users, if they match the search filter.

User search filter template

    userSearchFilterTemplate: '(&(cn=%v)(objectClass=person))'

An LDAP filter expression that determines whether a user object should be imported. User objects that do not match this filter are ignored during import.

The search filter template must contain the placeholder %v.

If the search filter does not contain a placeholder, it is impossible to search for a distinct user (e.g. during login). In this case LDAP will always return all user objects. This will result in locked user accounts, because the provided password is then tried against all returned user objects.

Manual user mapping

    manualUserMapping: false | true

Determines whether to use a custom mapping for specific user attributes. If set to false (default) LDAP attributes are automatically mapped to their corresponding fields in Relution. Automatic mapping is determined by the type of LDAP server.

If set to true it becomes possible to override the mapping for specified attribues. Attributes that are not defined continue to use automatic mapping.

Post user-sync action

    syncUsersActionWhenMissing: none | disable | delete

Determines how previously imported user objects should be treated, if they are no longer present in the search results. This may either be the case if a user was deleted from LDAP or if search criteria were modified in a way that now excludes this user from synchronization. This option has no effect, if syncUsers is set to false.

If this option is set to none (default, recommended), previously imported user objects are not modified if they are no longer found during search.

If this option is set to disable, previously imported user objects that are no longer found have their "Activated" flag set to false after synchronization completes. Please note that LDAP users that can no longer be found can’t never sign in, which means there is no requirement to disable them to prevent them from signing in. Synchronization will not re-enable a user account if future search results include the user again, which means manual action is required to enable a previously disabled account.

If this option is set to delete, previously imported user objects that are no longer found are permanently deleted. This will remove the user from all assigned groups and devices. If the user is currently signed in on a shared device, they are automatically logged out and will not be able to sign in again. If future search results include the user again, group and device assignments are not restored automatically. This means manual action is required to properly restore the account.

It is strongly recommended that administrators verify synchronization of users is working as intended before this option is set to disable or delete. If search filters are modified, we recommend to set this option to none until proper operation has been verified before enabling it again.

If synchronization returns zero results or encounters an error, this option is ignored to ensure users are not removed erroneously.

Use groups

    groupUseGroups: false | true

Determines whether groups are used. If set to false (default), no groups are imported. If set to true, groups that imported users are members of are imported.

Synchronize groups

    syncGroups: true

Determines whether groups should be imported periodically. If groupUseGroups is set to false this option has no effect.

If set to false (default) Relution only groups that imported users are a member of are imported. If set to true all group objects that match the search criteria are imported periodically.

Group synchronization interval

    syncGroupsInterval: 24h

Determines how often group objects should be synchronized, if syncGroups is set to true. This value can be specified in either days, hours, minutes or seconds. The lowest possible value is 30 minutes (30m). The default value is 24 hours (24h) which is equal to one day (1d). This value is ignored, if a syncGroupsSchedule is defined.

We generally do not recommend to use values lower than one day to ensure concurrent import operations do not overlap, which may result in undefined behavior.

Group synchronization schedule

    syncGroupsSchedule: '* * * */1 * *'

Determines how often group objects should be synchronized, if syncGroups is set to true. This value accepts Cron syntax, the non-standard values @hourly, @daily and @weekly are also supported. If syncGroupsSchedule is set to a non-empty value, the value of syncGroupsInterval is ignored.

If synchronizing a large number of groups on a tight schedule, synchronization may repeat immediately after completion. We recommend to use a schedule that is appropriate for the number of objects being imported and the speed of your server(s) and network connection.

Since: Relution Server 5.7

Group synchronization on startup

    syncGroupsOnStartup: true

The key syncGroupsOnStartup specifies whether group synchronization should run for the first time after the server completes startup. If the value is ommited, the default is used.

If syncGroupsInterval is used, this value defaults to true. Synchronization is run after the server has started and repeats periodically at the specified interval, unless this parameter is explicitly set to false. If set to false, initial synchronization is run for the first time after the specified interval has elapsed after server startup.

If syncGroupsSchedule is used, this value defaults to false. Synchronization is only run at the specified schedule, unless this parameter is explicitly set to true. If set to true, synchronization is also run once after server startup, before the schedule takes effect.

Since: Relution Server 5.7

Group search base

    groupSearchBase: # OU that contains the groups to import, relative to ldapBase

The search base of group objects, relative to the LDAP base. It works in conjunction with the search scope and filter template to define the subtree of entries that should be considered when searching for groups to import.

Group search scope

    groupSearchScope: 2

The search scope to use when searching for group objects.

If set to "base" (0), only the group that is specified by the search base is imported, if it matches the search filter.

If set to "one-level" (1), any group that is an immediate child of the base object specified by the search base is imported, if it matches the search filter. The base object itself is excluded.

If set to subtree (2), any child object as well as the base object itself are imported as groups, if they match the search filter.

Group search filter template

    groupSearchFilterTemplate: '(&(cn=%v)(objectClass=group))'

An LDAP filter expression that determines whether a group object should be imported. Group objects that do not match this filter are ignored during import.

The search filter template should contain the placeholder %v.

If the search filter does not contain a placeholder, it is impossible to search for a distinct group. In this case LDAP will always return all groups.

Manual group mapping

    manualGroupMapping: false | true

Determines whether to use a custom mapping for specific group attributes. If set to false (default) LDAP attributes are automatically mapped to their corresponding fields in Relution. Automatic mapping is determined by the type of LDAP server.

If set to true it becomes possible to override the mapping for specified attribues. Attributes that are not defined continue to use automatic mapping.

Synthetic default group

    groupSyntheticGroup: 'LDAP Users'

Specifies a synthetic group that all imported users are assigned to.

Synthetic groups

    'syntheticGroup_<Group Name 1>': (&(cn=<common-name>)(objectClass=<class>))
    'syntheticGroup_<Group Name 2>': (&(cn=<common-name>)(objectClass=<class>))

Specifies additional synthetic groups that imported users are assigned to. An imported user is assigned to a synthetic group, if the user matches its filter expression. Note that this can’t be used to import additional users. Only user objects that are imported based on the user search criteria are possible group members.

The name of a synthetic group is automatically prepended with the organization name. In the example above the synthetic group created by "Group Name 1" will be called "<ORG> Group Name 1".

A synthetic group is only created if it has at least one member. If syncUsers is set to false, this means a synthetic group is not created until at least one of its members has signed in for the first time.

Group role mapping

    groupRolesJson: |
      {
        "%o <Group Name 1>": [
          "%o <Role 1>",
          "%o <Role 2>",
          …
        ],
        "%o <Group Name 2>": [
          "%o <Role 3>",
          "%o <Role 4>",
          …
        ],
        …
      }

Specifies default assignments of groups to other (system) groups. The placeholder %o is automatically replaced with the organization name.

In the example above, the group "<ORG> Group Name 1" is assigned to the groups "<ORG> Role 1" and "<ORG> Role 2", the group "<ORG> Group Name 2" is assigned to the groups "<ORG> Role 3" and "<ORG> Role 4".

In combination with synthetic groups this makes it possible to automatically assign users to groups based on their LDAP attributes and to automatically assign these synthetic groups to existing (system) groups, which determines their permissions.

User to organization mapping

    organizationUserFilters:
      - <orgUniqueName_A>=<LDAP-filter-expression-A>
      - <orgUniqueName_B>=<LDAP-filter-expression-B>
      - <orgUniqueName_C>=<LDAP-filter-expression-C>
      …

Specifies the assignment of users to organizations based on their LDAP attributes. Users whose attributes match the LDAP filter expression are assigned to the organization identified by the unique name. Users who do not match any filter are assigned to the LDAP configuration’s default organization.

    organizationUserFilters:
      - <orgUniqueName_A>=dn=<expression_A>
      - <orgUniqueName_B>=dn=<expression_B>
      - <orgUniqueName_C>=dn=<expression_C>
      …
    expression:=[*<partial-dn>|*<partial-dn>*|<partial-dn>*]

Specifies the assigment of users to organizations based on their distinguished name (DN). Users whose distinguised name matches the expression are assigned to the organization identified by the unique name. The expression consists of a partial distinguished name that starts and/or ends with the wildcard character *. Users who do not match any filter are assigned to the LDAP configuration’s default organization.

If the partial DN starts with a wildcard character, users whose distinguished name ends with the specified value match this filter. If the partial DN ends with a wildcard character, users whose distinguished name starts with the specified value match this filter. If the partial DN starts and ends with a wildcard character, users whose distinguished name contains the specified value match this filter.

Group to organization mapping

    organizationGroupFilters:
      - <orgUniqueName_A>=<LDAP-filter-expression-A>
      - <orgUniqueName_B>=<LDAP-filter-expression-B>
      - <orgUniqueName_C>=<LDAP-filter-expression-C>
      …

Specifies the assignment of groups to organizations based on their LDAP attributes. Groups whose attributes match the LDAP filter expression are assigned to the organization identified by the unique name. Groups who do not match any filter are assigned to the LDAP configuration’s default organization.

    organizationGroupFilters:
      - <orgUniqueName_A>=dn=<expression_A>
      - <orgUniqueName_B>=dn=<expression_B>
      - <orgUniqueName_C>=dn=<expression_C>
      …
    expression:=[*<partial-dn>|*<partial-dn>*|<partial-dn>*]

Specifies the assigment of groups to organizations based on their distinguished name (DN). Groups whose distinguised name matches the expression are assigned to the organization identified by the unique name. The expression consists of a partial distinguished name that starts and/or ends with the wildcard character *. Groups who do not match any filter are assigned to the LDAP configuration’s default organization.

If the partial DN starts with a wildcard character, groups whose distinguished name ends with the specified value match this filter. If the partial DN ends with a wildcard character, groups whose distinguished name starts with the specified value match this filter. If the partial DN starts and ends with a wildcard character, groups whose distinguished name contains the specified value match this filter.