How to set up Mayan EDMS to authenticate against LDAP

Community contributed guides or tutorials for multiple topics like installations for other operating systems or platforms, monitoring, log aggregation, etc.
Post Reply
User avatar
rssfed23
Moderator
Moderator
Posts: 158
Joined: Mon Oct 14, 2019 1:18 pm
Location: United Kingdom
Contact:

How to set up Mayan EDMS to authenticate against LDAP

Post by rssfed23 » Mon Jan 13, 2020 12:53 pm

**This draft still has significant room for improvement. Please provide feedback in a reply as to how it worked (or didn't work) in your environment so we can optimise**

I wanted to share a quick guide to configuring LDAP on Mayan EDMS to help get people up and running quickly with LDAP.

There are some existing posts about LDAP, but some of them refer to older versions of Mayan EDMS and are no longer functional.

There are countless ways to configure a LDAP server, so that is outside the scope of this guide. I will be using a free cloud-hosted LDAP server provided by jumpcloud.com for this walkthrough, primarily because it's free for less than 10 users but also because it can proxy another backend SSO (such as G-Suite) and expose those users over LDAP which fits my use case perfectly. I will highlight areas you will need to consider/make changes for your own environment.
Once these steps have been proven by the community, I will migrate these instructions to the official documentation pages.

The community previously contributed a great example configuration file, which we will use as the basis of our setup.

Edit your docker-compose.yml file and add in the following variables in the environment section:

Code: Select all

      MAYAN_PIP_INSTALLS: python-ldap django_auth_ldap
      MAYAN_APT_INSTALLS: libsasl2-dev python3-dev libldap2-dev libssl-dev libgle3 build-essential autoconf libtool pkg-config gcc
      MAYAN_SETTINGS_MODULE: mayan_settings.myldapfile
For non-compose installs, these variables can be passed in using the -e option (just like how you pass in the database options):

Code: Select all

-e MAYAN_PIP_INSTALLS: python-ldap django_auth_ldap \
-e MAYAN_APT_INSTALLS: libsasl2-dev python3-dev libldap2-dev libssl-dev libgle3 build-essential autoconf libtool pkg-config gcc \
-e MAYAN_SETTINGS_MODULE: mayan_settings.myldapfile
These can be placed under your MAYAN_DATABASES entry. Ensure the correct indentation is retained as all the other environment variables.

Note: for Direct Installs, you can put these environment variables into your supervisor config at /etc/supervisor/conf.d/mayan.conf. Ensure you put a "," at the end of every environment variable you provide to Supervisor. The variables are the same ones used in the docker configuration.

Take note of the MAYAN_SETTINGS_MODULE value. Change the "myldapfile" name to something more relevant to yourself. We will name the configuration file after it later in the section.
You must retain the "mayan_settings." part before whatever you change "myldapfile" to.
Important: You must NOT name "myldapfile" just "ldap". It can be anything but "ldap". This is because we will be using a module later in the guide called "ldap" and conflicts will arise if they're named the same.

Download the example ldap configuration file, and place this into your $MAYAN_MEDIA_ROOT/mayan_settings/ directory.
For Docker installs following the official documentation, this will be /docker-volumes/mayan-edms/media/mayan_settings/

For Direct Installs, this will likely be in /opt/mayan-edms/media/mayan_settings

You must now rename the file so that it's filename matches what you changed "myldapfile" to in the environment variables section earlier.
For example, if my MAYAN_SETTINGS_MODULE value is mayan_settings.rssfed23ldap then the full path to the file should be /docker-volumes/mayan-edms/media/mayan_settings/rssfed23ldap.py. It is important to retain the .py file extension.

Next, we need to edit the example configuration file and tweak it to match our LDAP environment. I will walk through some example settings you might want to change here, but the values you need will be entirely dependent on how your LDAP server is set up and they are different for everyone.
Note: You will need to change even more details if you are trying to bind to Microsoft Active Directory. I don't have an AD environment to test against so the community will have to provide this guidance to members

Inside my myldapfile.py, the most important settings begin around line 37. These include:

Code: Select all

LDAP_ADMIN_DN = 'uid=bind,ou=Users,o=org,dc=jumpcloud,dc=com'
LDAP_BASE_DN = 'ou=Users,o=org,dc=jumpcloud,dc=com'
LDAP_PASSWORD = 'mybindpassword'
LDAP_USER_AUTO_CREATION = 'False'
LDAP_URL = 'ldap://ldap.jumpcloud.com:389'
These settings are going to be unique for your LDAP server. You will have to ensure you have a user with Bind permissions set up, and it is that users Bind password you need to enter above. The ADMIN_DN can be provided by your LDAP administrator.
These values will be different depending on your environment.

I also removed the LDAP_ADDITIONAL_USER_DN line as it's not required for my environment.

The other important part is the AUTH_LDAP_USER_SEARCH line. I recommend everyone read the upstream documentation, as it can help you taylor this file and the parameters in it to your needs. The existing USER_SEARCH line searches both the BASE_DN followed by the ADDITIONAL_USERS_DN, but for my environment those 2 are the same value so it resulted in no results.

So if you get everything set up correctly and you can see in the logs Mayan EDMS is talking to the LDAP server but logins are failing, I would recommend you check the USER_SEARCH parameter and modify it to your needs. Some LDAP environment store the username as the uid value some store it as username and some (like Active Directory) store it as SamAccountName (or similar).

Here's my LDAPSearch:

Code: Select all

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "ou=Users,o=org,dc=jumpcloud,dc=com", ldap.SCOPE_SUBTREE, '(uid=%(user)s)'
)
The example file is very descriptive and describes a couple of other ways to perform the search, such as using LDAPSearchUnion instead to search within multiple directories.

Finally, you will need to adjust the AUTH_LDAP_USER_ATTR_MAP to match what's shown in your directory.
This is so Mayan can get the correct First/Last name, email etc from the directory and map it to the correct user attributes. Mine is shown below, but yours will almost certainly be different:

Code: Select all

AUTH_LDAP_USER_ATTR_MAP = {
    'user': 'uid',
    'first_name': 'givenName',
    'last_name': 'sn',
    'email': 'mail'
}
Some users have had to add in their SECRET_KEY (also in the mayan_settings directory) to this file, but I think this is more to do with Active directory or ldaps. I did not require it for my setup.

Before we apply the changes, you must make sure there is an existing user in LDAP with a username matching an admin user in the existing Mayan environment. E.G: create a superuser called "rob" and then ensure that the "rob" user exists in LDAP already. This is because LDAP will become your single point of truth for user authentication and users will no longer be able to login with their existing local credentials and Mayan will map any users with the same username already in the groups/roles DB to ones provided by LDAP, so we need to ensure at least one username with admin capabilities exists so that user can grant other users access.

By default when a user logs into Mayan via LDAP for the first time they will be assigned no groups or roles and will have very limited access to the platform. This is where configuring correct LDAP groups and Mayan roles comes into play, which will be a further extension from this guide out of scope for today. As it stands, users will appear in the user list once they've logged into Mayan EDMS for the first time and someone with suitable rights can assign them the correct group/role from there.
Some users have had success in changing the AUTHENTICATION_BACKENDS line in the configuration file to include both local and LDAP users.

You're now ready to apply the changes. As usual, run a docker-compose down; docker-compose up -d to apply the changes, or "systemctl restart supervisor" for Direct Installs.
You must destroy the existing container as a new one has to be deployed to pick up the APT and PIP installs correctly. If you're not using Docker Compose (and you really should be!) then you can use docker rm -f <mayancontainername> and then do a new "docker run" using the correct environment variables specified above.

Once Mayan EDMS starts again, check you can login with a LDAP user. You will see debug entries in the log for every connection attempt which can be helpful in diagnosing issues. The majority of issues you will encounter are likely to be due to either the right USER_SEARCH string or the relevant base/bind DN settings.

Once confirmed working, you can modify

Code: Select all

ldap.set_option(ldap.OPT_DEBUG_LEVEL, 1)
to

Code: Select all

ldap.set_option(ldap.OPT_DEBUG_LEVEL, 0)
to disable debug logging.

Again, this is a basic quick start for LDAP. I encourage users to provide their configs/examples below for more advanced configuration. The above example is what we're using on https://mayan.app to demonstrate the capability functions as expected, but as LDAP is configured differently for every enterprise your mileage may vary. Don't hesitate to reach out for assistance, and we will log a bug if necessary, but as all ldap functionality is provided by an external module there's not a huge amount we can do within the Mayan EDMS codebase to mitigate issues in upstream code.

Many thanks and good luck!
Rob
Please don't PM for general support; start a new thread with your issue instead.

Post Reply