LDAP Authentication with Django

I recently wrote a web application for managing a seminar series at University. This system allows users to book times to give talks, view a list of upcoming talks, provides an iCalendar feed of scheduled talks and emails reminders to both attendees and speakers at various times throughout the week.

Rather than require users to have yet another set of log-in details to contend with, I decided to integrate the seminar management system with the department’s LDAP server. It turned out to be a reasonably easy process, which I will now attempt to explain!

To start off with, you need to install the django_auth_ldap and python-ldap modules. This can be done by running pip install python-ldap django-auth-ldap.

From there, you need to configure django-auth-ldap with the appropriate settings for your LDAP server. I will talk you through the settings my environment required, hopefully you’ll be able to adapt them to yours:

AUTH_LDAP_SERVER_URI = "ldap://ldap.some.domain.ac.uk:389"

AUTH_LDAP_SERVER_URI needs to be set to the LDAP server – hopefully this is quite self explanatory: ldap:// is the protocol that the LDAP server is using (this would be ldaps:// for LDAP over SSL/TLS), ldap.some.domain.ac.uk is the hostname of the LDAP server, 389 is the (default) port that the server is listening on (636 for LDAPS).

AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=People,dc=cs,dc=cardiff.ac.uk"

From there, we need to tell django-auth-ldap how to query our LDAP server. In this case, we’re telling django-auth-ldap that our users live in the People OU (organisational unit) under the cs.cardiff.ac.uk DN (distinguished name). uid=%(user)s is the templated part of the variable – %(user)s will be replaced with whatever username is passed in.

AUTH_LDAP_USER_ATTR_MAP = {"first_name": "givenName", "last_name": "sn", "email": "mail"}

Once we’ve defined the search filter for our LDAP directory, we need to define an attribute mapping from LDAP object -> Django user. This is done using a dictionary – the keys being the Django User field names, values being their LDAP attribute name.

Having configured the attribute mapping, set up the DN Template, and configured the Server URI, we should have enough for a very basic login to work – all that is left to do is to register django-auth-ldap as an authentication provider. You can do this by adding django_auth_ldap.backend.LDAPBackend to the AUTHENTICATION_BACKENDS tuple in your settings file, such that it looks like:

AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

You should then be able to log in to your Django site using your LDAP credentials. The LDAP server will be queried – if the bind is successful (i.e. if the supplied username and password match a valid user), a Django user will be created in your database.

It is possible to automatically apply user flags (such as is_staff and is_superuser) based on group membership of the authenticated user by using the AUTH_LDAP_USER_FLAGS_BY_GROUP setting. There is some server-specific config that needs to be done here (based on the directory type), but check out my code on GitHub for an admittedly very janky way of doing this.