LDAP Module
Content
Introduction
This module synchronizes users from LDAP sources into ApiOmat LDAPUsers and LDAPGroups. LDAPUser is a subclass of a User and can be used to authenticate within an application or via REST. For authorization purposes, these users may be members of LDAPGroups, an inherited class of Role, The authentication is done directly against the LDAP directory.
Configuration
Server Hostname |
Hostname(s) of the LDAP server(s), comma separated |
Server Port |
Port(s) of the LDAP server(s), comma separated, defaults to 389 |
Bind DN |
User for bind operation, leave empty for anomyous |
Bind DN password |
User password for bind operation |
Base DN |
Root node of Directory |
User filter |
Filter to get all Users |
User ID |
LDAP attribute name which contains a user ID, this field will be used for the userName, defaults is set to sAMAccountName |
Module of User class (optional) |
If you want to inherit the LDAPUser model, insert your modules name here to sync users to it. |
User class name (optional) |
If you want to inherit the LDAPUser model, insert your classname here to sync users to it. |
Activate sync LDAP groups |
If set to true, the synchronisation will include LDAP groups |
Group filter |
Filter to get all groups |
Group name attribute |
The attributes that identifies a group's name. Default is 'cn' |
Attributes holding member information |
Attributes holding distinguished names of members, separated by comma |
Module of Role class (optional) |
If you want to inherit the LDAPGroup model, insert your module's name here to sync groups to it. |
Role class name (optional) |
If you want to inherit the LDAPGroup model, insert your classname here to sync groups to it. |
Write user attributes map |
If set to true, all attributes will be written to the "userAttributes" map of the LDAPUser (additionally to the fields that match the attribute names) |
Overwrite missing attributes |
If set to true (defaults to false), fields on the class will be set to null, if the related attribute does not exist (or is empty) in LDAP. |
Disable auth for the sync |
If set to true (default), no auth checks will be done during user-synchronization. This increases the synchronization speed. |
Log all messages async |
If set to true, all messages of the synchronization process will be logged asynchronously. |
Module setup
Fill in the values fitting to your directory. An example would be:
Server Hostname |
ldap.example.com |
Server Port |
389 |
Bind DN |
uid=admin,ou=system |
Bind DN password |
123456 |
Base DN |
OU=com,DC=mycompany,DC=local |
User filter |
(objectCategory=Person) |
User ID |
uid |
Group filter |
(objectClass=group) |
Group name attribute |
cn |
Attributes holding member information |
uniquemember,member |
Custom user class
You can set a custom user class where the LDAP users get synced to. Therefore, you have to create a class that inherits from the LDAPUser in the LDAP module and then set the module name and class name in the module configuration for the properties Module of User class and User class name.
You can add additional attributes that match the attribute names for your entities on the LDAP server. The values of these attributes will automatically get mapped on the synchronized objects. If you only need the attributes that exist on your class and don't want to have all attributes stored in the userAttributes attribute of the LDAPUser, you can set the Write user attributes map flag to false in your module configuration. This may speed up the synchronization process a bit and saves bandwith when retrieving the users whithin a frontend.
Custom role class
As done for LDAP users, you can define a custom LDAP group subclass with creating a class inheriting from LDAPGroup and configuring its class name and module name using the configuration properties Role class name and Module of Role class.
The name attribute of the respective objects will be populated with the value of the attribute whose name can be configured with the property Group name attribute.
Synchronization
The synchronization process splits up into four parts.
In the first part, all users that exist on the LDAP server will be imported as LDAPUser (or whichever class you've set in your configuration). Users that already exist as the configured class instance will be updated if there are changes on the object. Otherwise the existing ApiOmat Object won't get touched.
In the second part, the existing ApiOmat users of the configured class will get checked whether they still exist on the LDAP server. If they do not exist anymore, they will be deleted from ApiOmat.
In the third part, if the module configuration property Activate sync LDAP groups is set to true, groups from the LDAP server are imported as LDAP groups in the same manner as users. Further, using the configuration provided with the property Attributes holding member information names of users imported in the predecessing parts are added to the members list of the respective LDAPGroup.
In the fourth part, if the module configuration property Activate sync LDAP groups is set to true, the existing ApiOmat groups of the configured class are checked whether they still exist on the LDAP server. If they do not exist anymore, they are deleted from ApiOmat.
If your LDAP server is not available at time of sync, the sync will be aborted and the data on ApiOmat remain unchanged. If there is an error during the creation, update or deletion of a single user (e.g. through an already existing user with the same user name in another class) the error will be logged and the synchronization will proceed with the next user.
If more than one LDAP server is configured, the module tries to connect to each server until it finds a working connection. The first working connection is then used for synchonization. The list of ports are related to the hostnames. If no ports are given, port 389 will always be used. Otherwise, you have to write the ports in the corresponding order of the hostnames. For instance, if you have one ldap server on ldap1.yourcompany.com listening on port 489 and another serverldap2.yourcompany.com on port 589, you have to enter "ldap1.yourcompany.com,ldap2.yourcompany.com" in the hosts configuration and "489,589" in the ports configuration field.
Use
All you have to do is configure the directory and wait until the next synchronization, which is done every hour. You can also manually start the synchronization via the MyModule page in dashboard or via REST:
curl -v $HOST/modules/ldap/spec/$APPNAME/sync/$APPNAME -u $USER:$PASSWORD
After a successful synchronization, you have to set the LDAPUser class (or if you configured another class for synchronization) as Authentication class in your backend configuration to authenticate to your LDAP server. Please note that we cannot synchronize the passwords of the users. Therefore you have to set the class as authentication class. We will then check the credentials against your LDAP server.
Your imported LDAPGroups' names may then be used in ApiOmat's access control lists of any class.
User Authentication via OAuth2 Tokens
The synchronized users are objects of the class LDAPUser, which inherits from the User class in the Basics module. So you can facilitate the OAuth2 functionality that already exists and for example send a request to "YOURHOST/yambas/oauth/token" to receive an access token for the user. For more info about how this works in ApiOmat, see this: ApiOmat and OAuth2.
In the case of LDAP, you might want to force the user to authenticate against the LDAP as soon as the access token is expired, instead of allowing them to use the previously received refresh token. To do this, just change the value yambas.oAuth2TokenValiditySeconds.standard.refresh in the apiomat.yaml to 0, or if you generally want refresh tokens to work and only not for LDAP, you can manually set the refresh token expiry in every request when fetching a token.