User Directory

Setup

# The URL of the LDAP server.
LDAP_AUTH_URL = "ldap://localhost:389"

# Initiate TLS on connection.
LDAP_AUTH_USE_TLS = False

# The LDAP search base for looking up users.
LDAP_AUTH_SEARCH_BASE = "ou=people,dc=example,dc=com"

# The LDAP class that represents a user.
LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson"

# User model fields mapped to the LDAP
# attributes that represent them.
LDAP_AUTH_USER_FIELDS = {
    "username": "uid",
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
}

# A tuple of django model fields used to uniquely identify a user.
LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",)


# Sets the login domain for Active Directory users.
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = None

# The LDAP username and password of a user for querying the LDAP database for user
# details. If None, then user synching is performed as an anonymous query.
LDAP_AUTH_CONNECTION_USERNAME = None
LDAP_AUTH_CONNECTION_PASSWORD = None

# Set connection/receive timeouts (in seconds) on the underlying `ldap3` library.
LDAP_AUTH_CONNECT_TIMEOUT = None
LDAP_AUTH_RECEIVE_TIMEOUT = None


How it works

When a user attempts to authenticate, a connection is made to the LDAP server, and the application attempts to bind using the provided username and password.

If the bind attempt is successful, the user details are loaded from the LDAP server and saved in a local Usermodel. The local model is only created once, and the details will be kept updated with the LDAP record details on every login.

Custom user filter

By default, any users within LDAP_AUTH_SEARCH_BASE and of the correct LDAP_AUTH_OBJECT_CLASS will be considered a valid user. You can apply further filtering by setting a custom LDAP_AUTH_FORMAT_SEARCH_FILTERS callable.

LDAP Auth format search filters
# settings.py
LDAP_AUTH_FORMAT_SEARCH_FILTERS = "path.to.your.custom_format_search_filters"

# path/to/your/module.py
from django_python3_ldap.utils import format_search_filters

def custom_format_search_filters(ldap_fields):
    # Add in simple filters.
    ldap_fields["memberOf"] = "foo"
    # Call the base format callable.
    search_filters = format_search_filters(ldap_fields)
    # Advanced: apply custom LDAP filter logic.
    search_filters.append("(|(memberOf=groupA)(memberOf=GroupB))")
    # All done!
    return search_filters


The returned list of search filters will be AND'd together to make the final search filter.