LDAP Settings

LDAP Settings are the settings used to configure LDAP connection to domains. They are configured inside the WAUTH_DOMAINS setting of your Django project settings file, as the value for each domain key.

Configuring

LDAP Settings can be represented as a regular Python Dictionary, like this:

WAUTH_DOMAINS = {
    "EXAMPLE": {
        "SERVER": "example.local",
        "SEARCH_BASE": "DC=example,DC=local",
        "USERNAME": "EXAMPLE\\bind_account",
        "PASSWORD": "*********",
    }
}

Or as an LDAPSettings object, like this:

WAUTH_DOMAINS = {
    "EXAMPLE": LDAPSettings(
        SERVER="example.local",
        SEARCH_BASE="DC=example,DC=local",
        USERNAME="EXAMPLE\\bind_account",
        PASSWORD="*********",
    ),
}

When using a Python Dictionary, each setting can be configured to a callback function that will be called with the specified domain as first and only argument. For example:

WAUTH_DOMAINS = {
    "EXAMPLE": {
        "USERNAME": lambda domain: f"{domain}\\bind_account",
    }
}

Using defaults

Sometimes when using multiple domains it is easier to configure settings globally or to specify defaults for unanticipated domains.

When configuring LDAP Settings as a Python Dictionary, this can be done by using the "__default__" key in WAUTH_DOMAINS settings. Every setting configured in the "__default__", and are not configured explicitly for the domain, in will propagate. For example:

WAUTH_DOMAINS = {
    "__default__": {
        "USE_SSL": True,
    },
    "EXAMPLE1": {
        "SERVER": "example.local",
        "SEARCH_BASE": "DC=example,DC=local",
        "USERNAME": "EXAMPLE\\bind_account",
        "PASSWORD": "*********",
        "USE_SSL": False,
    },
    "EXAMPLE2": {
        "SERVER": "example.local",
        "SEARCH_BASE": "DC=example,DC=local",
        "USERNAME": "EXAMPLE\\bind_account",
        "PASSWORD": "*********",
    }
}

In this case, EXAMPLE1 will have USE_SSL = False and EXAMPLE2 will have USE_SSL = True.

When using LDAPSettings objects, this can be done by inheriting and creating a custom LDAPSettings class. For example:

@dataclass()
class MyLDAPSettings(LDAPSettings):
    USE_SSL: bool = False


WAUTH_DOMAINS = {
    "EXAMPLE": MyLDAPSettings(
        SERVER="example.local",
        SEARCH_BASE="DC=example,DC=local",
        USERNAME="EXAMPLE\\bind_account",
        PASSWORD="*********",
    ),
}

Extending LDAP Settings

Sometimes it is useful to have some extra LDAP Settings for use with the LDAP Manager.

It is possible to create a custom LDAPSettings class and use it to configure the LDAP Settings for domains. Those extra setting will be available in the settings attribute of LDAPManager objects, and can be used throughout your code. Those settings should not affect the existing settings used by django-windowsauth for User synchronization or any other uses.

Custom LDAP Settings objects can be created by inheriting from the LDAPSettings dataclass, like so:

@dataclass()
class MyLDAPSettings(LDAPSettings):
    EXTRA_SETTING: str = "Hello, world!"


WAUTH_DOMAINS = {
    "EXAMPLE": MyLDAPSettings(
        SERVER="example.local",
        SEARCH_BASE="DC=example,DC=local",
        USERNAME="EXAMPLE\\bind_account",
        PASSWORD="*********",
    ),
}

Then the setting could be accessed from LDAPManager object:

>>> from windows_auth.ldap import get_ldap_manager
>>> manager = get_ldap_manager("EXAMPLE")
>>> manager.settings.EXTRA_SETTING
"Hello, world!"

Base Settings

SERVER

Type bool; Required.
FQDN, IP, or URL of the LDAP Server.

The Fully Qualified Domain Name, IP Address or complete URL in the scheme scheme://hostname:hostport of the LDAP Server. This setting will be used as host property for ldap3’s Server object.

When using Active Directory, this address should direct to a DC Server (Domain Controller) for the domain. By default, the FQDN of the domain itself will be resolved into your current configured DC Server. That way, in case you have multiple DC servers in your domain, you will be dynamically changing the server you are accessing.

USERNAME

Type str; Required.
The account to be used when binding to the LDAP Server.

The username in one of the Credentials Manager API’s formats (Down-Level or SPN) of a user with the permissions needed for your application. By default, read-only permissions for the user accounts that are able to authenticate via IIS Windows Authentication to your website is needed.

If you are planing to use NTLM authentication to your LDAP Server, the username must be in the Down-Level Logon Name format (DOMAIN\username).

In production, it is advised to use a dedicated Service Account to authorize your application in your Active Directory domain.

PASSWORD

Type str; Required.
Password of the user to be used when binding to the LDAP Server.

The password for the user used to authenticate to the LDAP Server.

Warning

It is highly advised not to store sensitive secrets like password in your code. You should use a safe and secure place to store the password. See the tutorial manage_secrets

SEARCH_BASE

Type str; Required.
The DN of the container used as starting point for LDAP searches.

When querying LDAP Directories, it is required to specify the root container to start the search from. Then, depending on the search scope, the objects are searched directly or indirectly in respect to the search base container.

For searches throughout all the domain’s containers, the search base DN is usually in the format DC=<domain name>,DC=<parent domain>.

USE_SSL

Type bool; Default to True; Not Required.
Connect to LDAP over secure port, usually 636.

This setting is used as the use_ssl parameter for the ldap3 Server object.

See also

ldap3 Server object docs https://ldap3.readthedocs.io/en/latest/server.html

READ_ONLY

Type bool; Default to True; Not Required.
Prevent modify, delete, add and modifyDn (move) operations.

Connect to the LDAP Server with a read only protection. This can farther minimize risks and vulnerabilities from unwanted operations against the LDAP Server.

This setting is used as the read_only parameter for the ldap3 Connection object.

Warning

This is not guaranteed to be a risk / vulnerabilities free connection, make sure to minimize the bind account’s permissions

COLLECT_METRICS

Type bool; Default to True; Not Required.
Collecting connection usage metrics.

Enabling ldap3’s Connection Metrics collection. Those usage metrics can be accessed via manager.get_usage() method.

Connection metrics can be saved automatically, see how to Collect Metrics

SERVER_OPTIONS

Type dict; Default to {}; Not Required.
Extra parameters for the ldap3 Server object.

A dictionary of extra keyword arguments to pass when creating the ldap3 Server object.

See also

For more information, see ldap3 docs https://ldap3.readthedocs.io/en/latest/server.html

CONNECTION_OPTIONS

Type dict; Default to {}; Not Required.
Extra parameters for the ldap3 Connection object.

A dictionary of extra keyword arguments to pass when creating the ldap3 Connection object.

See also

For more information, see ldap3 docs https://ldap3.readthedocs.io/en/latest/connection.html

PRELOAD_DEFINITIONS

Type tuple; Default is shown below; Not Required.
Preload LDAP schema for defining LDAP objects in Python.

A list of LDAP Object definitions to preload while connecting to the LDAP Server. This caches ldap3 ObjectDef objects on the LDAPManager object for each defined object class. The object definitions are later get used for parsing the objects received from querying the LDAP Directory. Preloading the object definitions can minimize the extra delay for first query for an object.

The definitions can be listed as a simple string referring to an LDAP object class, or a 2 valued tuple with the LDAP object class string on the first value, and a list of extra attributes on the second value. For example:

{
    "PRELOAD_DEFINITIONS": (
        ("user", ["sAMAccountName"]),
        "group"
    ),
}

The configuration above is the actual default configuration for this setting.

USER_FIELD_MAP

Type dict; Default is shown below; Not Required.
Translate User Model fields to LDAP User object attributes.

Provide a mapping for your Django User Model fields to the LDAP User object attributes. Those mappings are used when synchronizing Django Users to their related LDAP Users.

In case you using a Custom User Model in your Django project, you also will be able to map them to LDAP Attributes. This is mentioned in the tutorial Using Custom User Model Mappings.

Note

Make sure to specify the needed attributes when preloading definitions for non-default attributes.

{
    "USER_FIELD_MAP": {
        "username": "sAMAccountName",
        "first_name": "givenName",
        "last_name": "sn",
        "email": "mail",
    }
}

The configuration above is the actual default configuration for this setting.

USER_QUERY_FIELD

Type str; Default to username; Not Required.
The User Model field used for searching the related LDAP User object.

When synchronizing users to LDAP, they are first need to be searched. This setting can allow you to specify the Django User Model field that will be compared to the related LDAP Attribute using the USER_FIELD_MAP setting when searching for the related user.

This setting may be useful when using a Custom User Model in your Django project. This is mentioned in the tutorial Using Custom User Model Mappings.

Note

Make sure to use a unique field, that is unique at the LDAP side too. If multiple objects are found, the synchronization will fail.

USER_QUERY_FILTER

Type dict; Default to {"objectCategory": "person"}; Not Required.
Filters used when searching for a user from LDAP

LDAP filters applied when querying LDAP for a matching user. The dictionary is translated to ldap3’s (Simplified Query Language)[https://ldap3.readthedocs.io/en/latest/abstraction.html#simplified-query-language], then parsed to an ordinary LDAP filter. All special operators implemented by ldap3 are available both keys and values (e.g. {”&Age”: “> 21; < 65”}).

GROUP_ATTRS

Type str or tuple; Default to cn; Not Required.
The LDAP group attributes to search when matching to Django groups.

When synchronizing users against LDAP, you can replicate group memberships. When used, you may want to specify what LDAP attributes are used when comparing the Django Group’s names to LDAP Groups.

This setting can be a single string for comparing a single attribute, or a tuple for comparing multiple attributes. When comparing multiple attributes, if one of them matches the Django Group’s name, the user is added to that group.

Warning

The comparing is done on the Python side by the ldap3 library. Using many attributes to search groups may result in longer synchronization times.

SUPERUSER_GROUPS

Type tuple or str; Default to Domain Admins; Not Required.
LDAP Groups to check membership for setting Django User’s “is_superuser” flag.

When synchronizing users against LDAP, you can specify a list of LDAP Groups to match for setting the Django User’s is_superuser flag. If the user is member in one of the listed LDAP groups, the is_superuser flag will be set to True, otherwise it is set to False.

Configuring this setting to None will not modify the is_superuser flag.
Configuring this setting to a string is equal to a single length tuple.

The group membership is checked by comparing the groups listed in this setting to the LDAP Group Attributes listed in GROUP_ATTRS setting.

STAFF_GROUPS

Type tuple or str; Default to Administrators; Not Required.
LDAP Groups to check membership for setting Django User’s “is_staff” flag.

When synchronizing users against LDAP, you can specify a list of LDAP Groups to match for setting the Django User’s is_staff flag. If the user is member in one of the listed LDAP groups, the is_staff flag will be set to True, otherwise it is set to False.

Configuring this setting to None will not modify the is_staff flag.
Configuring this setting to a string is equal to a single length tuple.

The group membership is checked by comparing the groups listed in this setting to the LDAP Group Attributes listed in GROUP_ATTRS setting.

ACTIVE_GROUPS

Type tuple or str; Default to None; Not Required.
LDAP Groups to check membership for setting Django User’s “is_active” flag.

When synchronizing users against LDAP, you can specify a list of LDAP Groups to match for setting the Django User’s is_active flag. If the user is member in one of the listed LDAP groups, the is_active flag will be set to True, otherwise it is set to False.

Configuring this setting to None will not modify the is_active flag.
Configuring this setting to a string is equal to a single length tuple.

The group membership is checked by comparing the groups listed in this setting to the LDAP Group Attributes listed in GROUP_ATTRS setting.

PROPAGATE_GROUPS

Type bool; Default to True; Not Required.
Propagate groups in order Superusers > Staff > Active.

When set to True, all groups configured in SUPERUSER_GROUPS will be added to STAFF_GROUPS and ACTIVE_GROUPS, and groups configured in STAFF_GROUPS with be added to ACTIVE_GROUPS.

GROUP_MAP

Type dict; Default is {}; Not Required.
Map one or more LDAP Groups membership to Django Group membership.

When synchronizing users against LDAP, you can specify a mapping of LDAP Groups to Django Groups. If the user is member in one of the listed LDAP groups, it will be added to the respective Django Group.

The setting is configured as a dictionary where the keys are Django Groups names and the value is a string or a list of LDAP Groups. The LDAP Groups are compared using the attributes listed in the GROUP_ATTRS setting.

When a user synchronizes, LDAP group membership will be checked directly or in-directly for at least one of the listed groups. For each LDAP group that the user is found to be a member of, it will be added to the related Django group, otherwise it will be removed from it. Groups that are not listed in this setting will not be affected by this.

Warning

When a group that is configured in this setting is missing, it will be created automatically.

FLAG_MAP

Type dict; Default is {}; Not Required.
Map User object boolean fields to one or more LDAP Groups membership check.

Used to synchronize boolean fields from the User object as a group membership check. If the user is member in one of the listed LDAP groups, the respective boolean field will be set to True, otherwise it is set to False.

Configuring this setting to None will not modify the field.
Configuring this setting to a string is equal to a single length tuple.

The group membership is checked by comparing the groups listed in this setting to the LDAP Group Attributes listed in GROUP_ATTRS setting.

User’s is_superuser, is_staff and is_active are added automatically from settings SUPERUSER_GROUPS, STAFF_GROUPS and ACTIVE_GROUPS respectively.