Django LDAP Authentication Backend
django-auth-ldap is a Django authentication backend that integrates with LDAP (Lightweight Directory Access Protocol) services, allowing Django applications to authenticate users against an LDAP server. It provides rich configuration options for managing users, groups, and permissions. Currently at version 5.3.0, the library is actively maintained with frequent releases to support the latest Django and Python versions.
Warnings
- breaking Version 5.0.0 changed the handling of LDAPError during search operations and group mirroring. Previously, an LDAPError might have been silently ignored, leading to incomplete group mirroring. Now, an `LDAPError` during group mirroring can raise `AuthenticationFailed`, aborting the operation and preventing access control issues due to missing group memberships.
- breaking django-auth-ldap frequently drops support for older Python and Django versions. For instance, v5.3.0 dropped support for Python 3.9 and Django 5.1. Using an unsupported combination can lead to unexpected behavior or security vulnerabilities.
- gotcha The underlying `python-ldap` library requires system-level OpenLDAP development libraries and headers (e.g., `libldap2-dev` and `libsasl2-dev` on Debian/Ubuntu) to be installed before `pip install python-ldap` (which is a dependency of `django-auth-ldap`) can succeed. This is a common installation stumbling block.
- gotcha Setting `AUTH_LDAP_ALWAYS_UPDATE_USER = True` causes Django's `auth_user` table to be updated on every successful LDAP login. In high-traffic applications or APIs with frequent login attempts, this can lead to a significant load on the database due to repeated `UPDATE` queries, potentially causing performance bottlenecks.
- gotcha The order of `AUTHENTICATION_BACKENDS` is crucial. If `django.contrib.auth.backends.ModelBackend` is listed before `django_auth_ldap.backend.LDAPBackend`, Django will attempt to authenticate against its local database first. This might be desired for superusers or local accounts, but can cause confusion if all users are expected to authenticate via LDAP first.
Install
-
pip install django-auth-ldap -
sudo apt-get install libldap2-dev libsasl2-dev
Imports
- LDAPBackend
from django_auth_ldap.backend import LDAPBackend
- LDAPSearch
from django_auth_ldap.config import LDAPSearch
Quickstart
import os
import ldap
from django_auth_ldap.config import LDAPSearch, LDAPGroupQuery
AUTHENTICATION_BACKENDS = [
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
]
AUTH_LDAP_SERVER_URI = os.environ.get('AUTH_LDAP_SERVER_URI', 'ldap://localhost:389')
AUTH_LDAP_BIND_DN = os.environ.get('AUTH_LDAP_BIND_DN', '')
AUTH_LDAP_BIND_PASSWORD = os.environ.get('AUTH_LDAP_BIND_PASSWORD', '')
AUTH_LDAP_USER_SEARCH = LDAPSearch(
os.environ.get('AUTH_LDAP_USER_SEARCH_BASE', 'ou=users,dc=example,dc=com'),
ldap.SCOPE_SUBTREE,
"uid=%(user)s"
)
AUTH_LDAP_USER_ATTR_MAP = {
'first_name': 'givenName',
'last_name': 'sn',
'email': 'mail'
}
AUTH_LDAP_MIRROR_GROUPS = True
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
os.environ.get('AUTH_LDAP_GROUP_SEARCH_BASE', 'ou=groups,dc=example,dc=com'),
ldap.SCOPE_SUBTREE,
'(objectClass=groupOfNames)'
)
AUTH_LDAP_GROUP_TYPE = LDAPGroupQuery()
# Populate Group permissions
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_CACHE_TIMEOUT = 3600 # Cache for 1 hour
# Optional: Require valid TLS certificate from LDAP server
AUTH_LDAP_START_TLS = True
# AUTH_LDAP_GLOBAL_OPTIONS = {
# ldap.OPT_X_TLS_CACERTFILE: os.environ.get('LDAP_TLS_CACERTFILE', '/path/to/ca.pem'),
# ldap.OPT_X_TLS_CERTFILE: os.environ.get('LDAP_TLS_CERTFILE', '/path/to/client.pem'),
# ldap.OPT_X_TLS_KEYFILE: os.environ.get('LDAP_TLS_KEYFILE', '/path/to/client.key')
# }