Grav, authenticate users with LDAP

Convenient for configuring the site or modifying its content, grav's graphical interface also allows you to use an LDAP server to authenticate its users. Here's how we did it (with Active Directory).

Whenever a new application is added to a network, we must answer the question of authentication of its users.

Of course, all applications can manage their own user database. Just create accounts for each authorised person and they will be able to use the application (after changing the default password that you used of course).

After a while, by installing apps, your users end up with too many accounts that they need to manage. It’s painful for them (think of passwords) and for you (managing staff entries and exits involves creating and deleting these accounts).

geralt @ pixabay
geralt @ pixabay

Fortunately, all serious applications also manage a connection to a centralised user directory. Usually with LDAP because it works quite well and is supported in both the Unix and Windows worlds (via Active Directory).

This is of course the case with grav (the CMS we use) which has a plugin for this. Once installed and configured, you no longer need to manage accounts in grav, everything will be centralized (in your AD).

After having configured two details on the server (adding the php module and the TLS root certificate), all you have to do is install the plugin, configure it so that it connects to the AD and, last detail, set the access rights of these particular users.

Server setup

In fact, I had first installed the plugin, only to realise that it was not working because my server was not yet prepared to receive it...

PHP LDAP module

Rather than reinventing the wheel, the developers of grav relied on the functions already provided by PHP. These functions are grouped together in a specific module, "php-ldap".

If your server does not already have this module, it must be installed. On Ubuntu, the following command line will do the trick:

sudo apt-get install php-ldap

With it, the module will be able to perform the LDAP operations it needs.

Install the root certificate of your PKI

As you have done things right, your directory surely does not listen directly in LDAP but secures its communications with TLS (in LDAPs or via starttls).

You could configure the grav plugin not to check the server's certificate when it connects to it, but that would completely nullify TLS's interest as an attacker could then intercept your communications.

The best practice is therefore to deploy your root certificate on the server where grav is running. Thus, when it connects to the LDAP server, he can verify that the LDAP server's certificate is signed by an authority that he recognises.

This task is actually extremely simple, you just have to copy your CA in a specific directory then tell the system to update its list of CAs. Assuming that the CA is in the root.arsouyes.org.crt file, these two commands will do the job:

sudo mv root.arsouyes.org.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

Plugin installation

Installing the plugin does not pose any particular problem, just follow the usual steps for grav plugins.

On command line

If you prefer command prompts over graphical interfaces, you can use grav's built-in package manager. Once in the directory where you have deployed grav, run the following command:

./bin/gpm install login-ldap

Note that if all your files are owned by another user (i.e. www-data), you must use sudo to launch the manager with the identity of that user. The command is then slightly modified as follows:

sudo -u www-data ./bin/gpm install login-ldap

Via the graphical interface

If you prefer the graphical user interface, you can go through the “Plugins” menu on the right, then the “+ Add” button at the top, enter the name of the plugin in the input field then click on the “+ Install” button ".

Plugin installation
Plugin installation

You can also choose to click on the "Login LDAP" link to see the plugin information. Another “+ Install” button will be available, you can click on that too.

The interface will then ask you to confirm, click on "✔ Continue".

Installation confirmation
Installation confirmation

Configuration via the graphical interface

We can now start configuring the plugin. The documentation is clear, but it lacks a bit of detail (especially for Active Directory). A user had gone before us and had documented his findings in a ticket on github but since some details are missing, we have completed.

Before you start, and since this kind of system does not usually work on the first try, here are two tips to make your life easier:

  1. Use two browsers, one logged in with the admin account (and stay logged in, no matter what), the other to test the connection with LDAP.
  2. Disabling brute force protection while testing (otherwise, grav will block you after 5 failed attempts). It is in the configuration of the "login" plugin, "Security" tab, change the value of "Max logins count" to 0 for the duration of your tests.

Authentication

Go to the plugin configuration page. To do this, go to the "Plugins" menu then click on the "LDAP Login" link.

The first tab allows you to configure authentication via LDAP. Let's start with the first area, “Server Configuration” for network settings.

Server connection
Server connection

If you prefer starttls, leave the port number at 389 and "Use SSL" at No. On the other hand, you will have to set "Negociate TLS" to Yes.

We continue with the ldap configuration proper. Active Directory version in our case, here are the fields that we had to change (the DN values for users and groups are fictitious and to be adapted to your situations):

LDAP fields setup
LDAP fields setup

With these settings, your users can now authenticate through their active directory account. However, since they do not have any rights at the moment, the login page will return an error, this is normal, we will take care of that in the next step.

Access rights

The documentation is not very clear on this point because we are on the border between two systems:

So that it works, you must therefore tell the plugin how to add the rights to your users, and for that, we go to the "advanced" tab and more particularly the "Group Access Level" field to adapt them to your case.

Here is an adaptation of the arsouyes. webmaster is actually the name of a group in the Active Directory including accounts authorized to connect to the grav application as administrators:

webmasters:
    admin:
        login: true
        super: true
    site:
        login: true

The documentation (which follows the input field) says it: it only concerns LDAP groups. So no need to test values in "Default Groups" hoping that it uses information from this field because the default group is only used if your user does not have a group in LDAP (this is rarely the case) and that the corresponding group is defined in grav itself.

Configuration file

If you don't want to go through the site's graphical interface to configure the plugin, you can directly edit the plugin's configuration file. It is located in the user/config/plugins/login-ldap.yaml file. Here is ours once the previous steps have been completed (you should therefore adapt it to your particularities):

enabled: true
host: addc.arsouyes.org
port: 636
version: 3
ssl: true
start_tls: false
opt_referrals: false
user_dn: '[username]@arsouyes.org'
search_dn: 'OU=users,DC=arsouyes,DC=org'
group_dn: 'OU=groups,DC=arsouyes,DC=org'
group_query: '(&(cn=*)(member=[dn]))'
group_indentifier: cn
map_username: sAMAccountName
map_fullname: 'givenName lastName'
map_email: mail
map_dn: distinguishedName
save_grav_user: false
store_ldap_data: false
default_access_levels:
  groups:
    - ldap_users
  access:
    site:
      login: 'true'
    groups: "webmasters:\n    admin:\n      login: true\n      super: true\n    site:\n      login: true\n"
blacklist_ldap_fields: null

And after ?

Now your users can authenticate with their active directory account on your grav application. You can even use the groups in your AD to manage their access rights (by adapting our example a little more of course).

For the record, when we tested this plugin, in July 2020, we found a bug. When a user logs out, the system crashes... This was due to the plugin continuing to want to authenticate the user (empty since he had logged out). Someone found out in March 2020 (#14) and a fix had been developed. It is now integrated into the plugin since November 2020.

You can also benefit from synergy with other systems; if you are versioning site content through the git-sync plugin the commit author can be the logged in user. As long as your GitLab is also connected to LDAP, they will be in common 😉.