| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853 |
- ================================
- Django authentication using LDAP
- ================================
- This authentication backend enables a Django project to authenticate against any
- LDAP server. To use it, add :class:`django_auth_ldap.backend.LDAPBackend` to
- AUTHENTICATION_BACKENDS. It is not necessary to add `django_auth_ldap` to
- INSTALLED_APPLICATIONS unless you would like to run the unit tests. LDAP
- configuration can be as simple as a single distinguished name template, but
- there are many rich options for working with
- :class:`~django.contrib.auth.models.User` objects, groups, and permissions. This
- backend depends on the `python-ldap <http://www.python-ldap.org/>`_ module.
- .. note::
- :class:`~django_auth_ldap.backend.LDAPBackend` does not inherit from
- :class:`~django.contrib.auth.backends.ModelBackend`. It is possible to use
- :class:`~django_auth_ldap.backend.LDAPBackend` exclusively by configuring it
- to draw group membership from the LDAP server. However, if you would like to
- assign permissions to individual users or add users to groups within Django,
- you'll need to have both backends installed:
- .. code-block:: python
- AUTHENTICATION_BACKENDS = (
- 'django_auth_ldap.backend.LDAPBackend',
- 'django.contrib.auth.backends.ModelBackend',
- )
- Configuring basic authentication
- ================================
- If your LDAP server isn't running locally on the default port, you'll want to
- start by setting :ref:`AUTH_LDAP_SERVER_URI` to point to your server.
- .. code-block:: python
- AUTH_LDAP_SERVER_URI = "ldap://ldap.example.com"
- That done, the first step is to authenticate a username and password against the
- LDAP service. There are two ways to do this, called search/bind and simply bind.
- The first one involves connecting to the LDAP server either anonymously or with
- a fixed account and searching for the distinguished name of the authenticating
- user. Then we can attempt to bind again with the user's password. The second
- method is to derive the user's DN from his username and attempt to bind as the
- user directly.
- Because LDAP searches appear elsewhere in the configuration, the
- :class:`~django_auth_ldap.config.LDAPSearch` class is provided to encapsulate
- search information. In this case, the filter parameter should contain the
- placeholder ``%(user)s``. A simple configuration for the search/bind approach
- looks like this (some defaults included for completeness)::
- import ldap
- from django_auth_ldap.config import LDAPSearch
- AUTH_LDAP_BIND_DN = ""
- AUTH_LDAP_BIND_PASSWORD = ""
- AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
- ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
- This will perform an anonymous bind, search under
- ``"ou=users,dc=example,dc=com"`` for an object with a uid matching the user's
- name, and try to bind using that DN and the user's password. The search must
- return exactly one result or authentication will fail. If you can't search
- anonymously, you can set :ref:`AUTH_LDAP_BIND_DN` to the distinguished name of
- an authorized user and :ref:`AUTH_LDAP_BIND_PASSWORD` to the password.
- To skip the search phase, set :ref:`AUTH_LDAP_USER_DN_TEMPLATE` to a template
- that will produce the authenticating user's DN directly. This template should
- have one placeholder, ``%(user)s``. If the previous example had used
- ``ldap.SCOPE_ONELEVEL``, the following would be a more straightforward (and
- efficient) equivalent::
- AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"
- By default, LDAP connections are unencrypted and make no attempt to protect
- sensitive information, such as passwords. When communicating with an LDAP server
- on localhost or on a local network, this might be fine. If you need a secure
- connection to the LDAP server, you can either use an ``ldaps://`` URL or enable
- the StartTLS extension. The latter is generally the preferred mechanism. To
- enable StartTLS, set :ref:`AUTH_LDAP_START_TLS` to ``True``::
- AUTH_LDAP_START_TLS = True
- Working with groups
- ===================
- Working with groups in LDAP can be a tricky business, mostly because there are
- so many different kinds. This module includes an extensible API for working with
- any kind of group and includes implementations for the most common ones.
- :class:`~django_auth_ldap.config.LDAPGroupType` is a base class whose concrete
- subclasses can determine group membership for particular grouping mechanisms.
- Three built-in subclasses cover most grouping mechanisms:
- * :class:`~django_auth_ldap.config.PosixGroupType`
- * :class:`~django_auth_ldap.config.MemberDNGroupType`
- * :class:`~django_auth_ldap.config.NestedMemberDNGroupType`
- posixGroup objects are somewhat specialized, so they get their own class. The
- other two cover mechanisms whereby a group object stores a list of its members
- as distinguished names. This includes groupOfNames, groupOfUniqueNames, and
- Active Directory groups, among others. The nested variant allows groups to
- contain other groups, to as many levels as you like. For convenience and
- readability, several trivial subclasses of the above are provided:
- * :class:`~django_auth_ldap.config.GroupOfNamesType`
- * :class:`~django_auth_ldap.config.NestedGroupOfNamesType`
- * :class:`~django_auth_ldap.config.GroupOfUniqueNamesType`
- * :class:`~django_auth_ldap.config.NestedGroupOfUniqueNamesType`
- * :class:`~django_auth_ldap.config.ActiveDirectoryGroupType`
- * :class:`~django_auth_ldap.config.NestedActiveDirectoryGroupType`
- To get started, you'll need to provide some basic information about your LDAP
- groups. :ref:`AUTH_LDAP_GROUP_SEARCH` is an
- :class:`~django_auth_ldap.config.LDAPSearch` object that identifies the set of
- relevant group objects. That is, all groups that users might belong to as well
- as any others that we might need to know about (in the case of nested groups,
- for example). :ref:`AUTH_LDAP_GROUP_TYPE` is an instance of the class
- corresponding to the type of group that will be returned by
- :ref:`AUTH_LDAP_GROUP_SEARCH`. All groups referenced elsewhere in the
- configuration must be of this type and part of the search results.
- .. code-block:: python
- import ldap
- from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
-
- AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=groups,dc=example,dc=com",
- ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
- )
- AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
- The simplest use of groups is to limit the users who are allowed to log in. If
- :ref:`AUTH_LDAP_REQUIRE_GROUP` is set, then only users who are members of that
- group will successfully authenticate::
- AUTH_LDAP_REQUIRE_GROUP = "cn=enabled,ou=groups,dc=example,dc=com"
- More advanced uses of groups are covered in the next two sections.
- User objects
- ============
- Authenticating against an external source is swell, but Django's auth module is
- tightly bound to the :class:`django.contrib.auth.models.User` model. Thus, when
- a user logs in, we have to create a :class:`~django.contrib.auth.models.User`
- object to represent him in the database.
- The only required field for a user is the username, which we obviously have. The
- :class:`~django.contrib.auth.models.User` model is picky about the characters
- allowed in usernames, so :class:`~django_auth_ldap.backend.LDAPBackend` includes
- a pair of hooks,
- :meth:`~django_auth_ldap.backend.LDAPBackend.ldap_to_django_username` and
- :meth:`~django_auth_ldap.backend.LDAPBackend.django_to_ldap_username`, to
- translate between LDAP usernames and Django usernames. You'll need this, for
- example, if your LDAP names have periods in them. You can subclass
- :class:`~django_auth_ldap.backend.LDAPBackend` to implement these hooks; by
- default the username is not modified. :class:`~django.contrib.auth.models.User`
- objects that are authenticated by :class:`~django_auth_ldap.backend.LDAPBackend`
- will have an :attr:`~django.contrib.auth.models.User.ldap_username` attribute
- with the original (LDAP) username.
- :attr:`~django.contrib.auth.models.User.username` will, of course, be the Django
- username.
- LDAP directories tend to contain much more information about users that you may
- wish to propagate. A pair of settings, :ref:`AUTH_LDAP_USER_ATTR_MAP` and
- :ref:`AUTH_LDAP_PROFILE_ATTR_MAP`, serve to copy directory information into
- :class:`~django.contrib.auth.models.User` and profile objects. These are
- dictionaries that map user and profile model keys, respectively, to LDAP
- attribute names::
- AUTH_LDAP_USER_ATTR_MAP = {"first_name": "givenName", "last_name": "sn"}
- AUTH_LDAP_PROFILE_ATTR_MAP = {"home_directory": "homeDirectory"}
- Only string fields can be mapped to attributes. Boolean fields can be defined by
- group membership::
- AUTH_LDAP_USER_FLAGS_BY_GROUP = {
- "is_active": "cn=active,ou=groups,dc=example,dc=com",
- "is_staff": "cn=staff,ou=groups,dc=example,dc=com",
- "is_superuser": "cn=superuser,ou=groups,dc=example,dc=com"
- }
- By default, all mapped user fields will be updated each time the user logs in.
- To disable this, set :ref:`AUTH_LDAP_ALWAYS_UPDATE_USER` to ``False``. If you
- need to populate a user outside of the authentication process—for example, to
- create associated model objects before the user logs in for the first time—you
- can call :meth:`django_auth_ldap.backend.LDAPBackend.populate_user`. You'll
- need an instance of :class:`~django_auth_ldap.backend.LDAPBackend`, which you
- can create yourself if necessary.
- If you need to access multi-value attributes or there is some other reason that
- the above is inadequate, you can also access the user's raw LDAP attributes.
- ``user.ldap_user`` is an object with two public properties:
- * ``dn``: The user's distinguished name.
- * ``attrs``: The user's LDAP attributes as a dictionary of lists of string
- values.
- Python-ldap returns all attribute values as utf8-encoded strings. For
- convenience, this module will try to decode all values into Unicode strings. Any
- string that can not be successfully decoded will be left as-is; this may apply
- to binary values such as Active Directory's objectSid.
- .. note::
- Users created by :class:`~django_auth_ldap.backend.LDAPBackend` will have an
- unusable password set. This will only happen when the user is created, so if
- you set a valid password in Django, the user will be able to log in through
- :class:`~django.contrib.auth.backends.ModelBackend` (if configured) even if
- he is rejected by LDAP. This is not generally recommended, but could be
- useful as a fail-safe for selected users in case the LDAP server is
- unavailable.
- Permissions
- ===========
- Groups are useful for more than just populating the user's ``is_*`` fields.
- :class:`~django_auth_ldap.backend.LDAPBackend` would not be complete without
- some way to turn a user's LDAP group memberships into Django model permissions.
- In fact, there are two ways to do this.
- Ultimately, both mechanisms need some way to map LDAP groups to Django groups.
- Implementations of :class:`~django_auth_ldap.config.LDAPGroupType` will have an
- algorithm for deriving the Django group name from the LDAP group. Clients that
- need to modify this behavior can subclass the
- :class:`~django_auth_ldap.config.LDAPGroupType` class. All of the built-in
- implementations take a ``name_attr`` argument to ``__init__``, which
- specifies the LDAP attribute from which to take the Django group name. By
- default, the ``cn`` attribute is used.
- The least invasive way to map group permissions is to set
- :ref:`AUTH_LDAP_FIND_GROUP_PERMS` to ``True``.
- :class:`~django_auth_ldap.backend.LDAPBackend` will then find all of the LDAP
- groups that a user belongs to, map them to Django groups, and load the
- permissions for those groups. You will need to create the Django groups
- yourself, generally through the admin interface.
- To minimize traffic to the LDAP server,
- :class:`~django_auth_ldap.backend.LDAPBackend` can make use of Django's cache
- framework to keep a copy of a user's LDAP group memberships. To enable this
- feature, set :ref:`AUTH_LDAP_CACHE_GROUPS` to ``True``. You can also set
- :ref:`AUTH_LDAP_GROUP_CACHE_TIMEOUT` to override the timeout of cache entries
- (in seconds).
- .. code-block:: python
- AUTH_LDAP_CACHE_GROUPS = True
- AUTH_LDAP_GROUP_CACHE_TIMEOUT = 300
- The second way to turn LDAP group memberships into permissions is to mirror the
- groups themselves. If :ref:`AUTH_LDAP_MIRROR_GROUPS` is ``True``, then every
- time a user logs in, :class:`~django_auth_ldap.backend.LDAPBackend` will update
- the database with the user's LDAP groups. Any group that doesn't exist will be
- created and the user's Django group membership will be updated to exactly match
- his LDAP group membership. Note that if the LDAP server has nested groups, the
- Django database will end up with a flattened representation.
- This approach has two main differences from :ref:`AUTH_LDAP_FIND_GROUP_PERMS`.
- First, :ref:`AUTH_LDAP_FIND_GROUP_PERMS` will query for LDAP group membership
- either for every request or according to the cache timeout. With group
- mirroring, membership will be updated when the user authenticates. This may not
- be appropriate for sites with long session timeouts. The second difference is
- that with :ref:`AUTH_LDAP_FIND_GROUP_PERMS`, there is no way for clients to
- determine a user's group memberships, only their permissions. If you want to
- make decisions based directly on group membership, you'll have to mirror the
- groups.
- :class:`~django_auth_ldap.backend.LDAPBackend` has one more feature pertaining
- to permissions, which is the ability to handle authorization for users that it
- did not authenticate. For example, you might be using Django's RemoteUserBackend
- to map externally authenticated users to Django users. By setting
- :ref:`AUTH_LDAP_AUTHORIZE_ALL_USERS`,
- :class:`~django_auth_ldap.backend.LDAPBackend` will map these users to LDAP
- users in the normal way in order to provide authorization information. Note that
- this does *not* work with :ref:`AUTH_LDAP_MIRROR_GROUPS`; group mirroring is a
- feature of authentication, not authorization.
- Logging
- =======
- :class:`~django_auth_ldap.backend.LDAPBackend` uses the standard logging module
- to log debug and warning messages to the logger named ``'django_auth_ldap'``. If
- you need debug messages to help with configuration issues, you should add a
- handler to this logger. Note that this logger is initialized with a level of
- NOTSET, so you may need to change the level of the logger in order to get debug
- messages.
- .. code-block:: python
- import logging
- logger = logging.getLogger('django_auth_ldap')
- logger.addHandler(logging.StreamHandler())
- logger.setLevel(logging.DEBUG)
- More options
- ============
- Miscellaneous settings for :class:`~django_auth_ldap.backend.LDAPBackend`:
- * :ref:`AUTH_LDAP_GLOBAL_OPTIONS`: A dictionary of options to pass to
- python-ldap via ``ldap.set_option()``.
- * :ref:`AUTH_LDAP_CONNECTION_OPTIONS`: A dictionary of options to pass to
- each LDAPObject instance via ``LDAPObject.set_option()``.
- Performance
- ===========
- :class:`~django_auth_ldap.backend.LDAPBackend` is carefully designed not to
- require a connection to the LDAP service for every request. Of course, this
- depends heavily on how it is configured. If LDAP traffic or latency is a concern
- for your deployment, this section has a few tips on minimizing it, in decreasing
- order of impact.
- #. **Cache groups**. If :ref:`AUTH_LDAP_FIND_GROUP_PERMS` is ``True``, the
- default behavior is to reload a user's group memberships on every
- request. This is the safest behavior, as any membership change takes
- effect immediately, but it is expensive. If possible, set
- :ref:`AUTH_LDAP_CACHE_GROUPS` to ``True`` to remove most of this traffic.
- Alternatively, you might consider using :ref:`AUTH_LDAP_MIRROR_GROUPS`
- and relying on :class:`~django.contrib.auth.backends.ModelBackend` to
- supply group permissions.
- #. **Don't access user.ldap_user.***. These properties are only cached
- on a per-request basis. If you can propagate LDAP attributes to a
- :class:`~django.contrib.auth.models.User` or profile object, they will
- only be updated at login. ``user.ldap_user.attrs`` triggers an LDAP
- connection for every request in which it's accessed. If you're not using
- :ref:`AUTH_LDAP_USER_DN_TEMPLATE`, then accessing ``user.ldap_user.dn``
- will also trigger an LDAP connection.
- #. **Use simpler group types**. Some grouping mechanisms are more expensive
- than others. This will often be outside your control, but it's important
- to note that the extra functionality of more complex group types like
- :class:`~django_auth_ldap.config.NestedGroupOfNamesType` is not free and
- will generally require a greater number and complexity of LDAP queries.
- #. **Use direct binding**. Binding with
- :ref:`AUTH_LDAP_USER_DN_TEMPLATE` is a little bit more efficient than
- relying on :ref:`AUTH_LDAP_USER_SEARCH`. Specifically, it saves two LDAP
- operations (one bind and one search) per login.
- Example configuration
- =====================
- Here is a complete example configuration from :file:`settings.py` that exercises
- nearly all of the features. In this example, we're authenticating against a
- global pool of users in the directory, but we have a special area set aside for
- Django groups (ou=django,ou=groups,dc=example,dc=com). Remember that most of
- this is optional if you just need simple authentication. Some default settings
- and arguments are included for completeness.
- .. code-block:: python
- import ldap
- from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
- # Baseline configuration.
- AUTH_LDAP_SERVER_URI = "ldap://ldap.example.com"
- AUTH_LDAP_BIND_DN = "cn=django-agent,dc=example,dc=com"
- AUTH_LDAP_BIND_PASSWORD = "phlebotinum"
- AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
- ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
- # or perhaps:
- # AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"
- # Set up the basic group parameters.
- AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=django,ou=groups,dc=example,dc=com",
- ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
- )
- AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn")
- # Only users in this group can log in.
- AUTH_LDAP_REQUIRE_GROUP = "cn=enabled,ou=django,ou=groups,dc=example,dc=com"
- # Populate the Django user from the LDAP directory.
- AUTH_LDAP_USER_ATTR_MAP = {
- "first_name": "givenName",
- "last_name": "sn",
- "email": "mail"
- }
- AUTH_LDAP_PROFILE_ATTR_MAP = {
- "employee_number": "employeeNumber"
- }
- AUTH_LDAP_USER_FLAGS_BY_GROUP = {
- "is_active": "cn=active,ou=django,ou=groups,dc=example,dc=com",
- "is_staff": "cn=staff,ou=django,ou=groups,dc=example,dc=com",
- "is_superuser": "cn=superuser,ou=django,ou=groups,dc=example,dc=com"
- }
-
- # This is the default, but I like to be explicit.
- AUTH_LDAP_ALWAYS_UPDATE_USER = True
-
- # Use LDAP group membership to calculate group permissions.
- AUTH_LDAP_FIND_GROUP_PERMS = True
- # Cache group memberships for an hour to minimize LDAP traffic
- AUTH_LDAP_CACHE_GROUPS = True
- AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
- # Keep ModelBackend around for per-user permissions and maybe a local
- # superuser.
- AUTHENTICATION_BACKENDS = (
- 'django_auth_ldap.backend.LDAPBackend',
- 'django.contrib.auth.backends.ModelBackend',
- )
- Reference
- =========
- Settings
- --------
- .. _AUTH_LDAP_ALWAYS_UPDATE_USER:
- AUTH_LDAP_ALWAYS_UPDATE_USER
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``True``
- If ``True``, the fields of a :class:`~django.contrib.auth.models.User` object
- will be updated with the latest values from the LDAP directory every time the
- user logs in. Otherwise the :class:`~django.contrib.auth.models.User` object
- will only be populated when it is automatically created.
- .. _AUTH_LDAP_AUTHORIZE_ALL_USERS:
- AUTH_LDAP_AUTHORIZE_ALL_USERS
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``False``
- If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` will be able furnish
- permissions for any Django user, regardless of which backend authenticated it.
- .. _AUTH_LDAP_BIND_DN:
- AUTH_LDAP_BIND_DN
- ~~~~~~~~~~~~~~~~~
- Default: ``''`` (Empty string)
- The distinguished name to use when binding to the LDAP server (with
- :ref:`AUTH_LDAP_BIND_PASSWORD`). Use the empty string (the default) for an
- anonymous bind. To authenticate a user, we will bind with that user's DN and
- password, but for all other LDAP operations, we will be bound as the DN in this
- setting. For example, if :ref:`AUTH_LDAP_USER_DN_TEMPLATE` is not set, we'll use
- this to search for the user. If :ref:`AUTH_LDAP_FIND_GROUP_PERMS` is ``True``,
- we'll also use it to determine group membership on subsequent requests.
- .. _AUTH_LDAP_BIND_PASSWORD:
- AUTH_LDAP_BIND_PASSWORD
- ~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``''`` (Empty string)
- The password to use with :ref:`AUTH_LDAP_BIND_DN`.
- .. _AUTH_LDAP_CACHE_GROUPS:
- AUTH_LDAP_CACHE_GROUPS
- ~~~~~~~~~~~~~~~~~~~~~~
- Default: ``False``
- If ``True``, LDAP group membership will be cached using Django's cache
- framework. The cache timeout can be customized with
- :ref:`AUTH_LDAP_GROUP_CACHE_TIMEOUT`.
- .. _AUTH_LDAP_CONNECTION_OPTIONS:
- AUTH_LDAP_CONNECTION_OPTIONS
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``{}``
- A dictionary of options to pass to each connection to the LDAP server via
- ``LDAPObject.set_option()``. Keys are ``ldap.OPT_*`` constants.
- .. _AUTH_LDAP_GROUP_CACHE_TIMEOUT:
- AUTH_LDAP_GROUP_CACHE_TIMEOUT
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``None``
- If :ref:`AUTH_LDAP_CACHE_GROUPS` is ``True``, this is the cache timeout for
- group memberships. If ``None``, the global cache timeout will be used.
- .. _AUTH_LDAP_FIND_GROUP_PERMS:
- AUTH_LDAP_FIND_GROUP_PERMS
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``False``
- If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` will furnish group
- permissions based on the LDAP groups the authenticated user belongs to.
- :ref:`AUTH_LDAP_GROUP_SEARCH` and :ref:`AUTH_LDAP_GROUP_TYPE` must also be set.
- .. _AUTH_LDAP_GLOBAL_OPTIONS:
- AUTH_LDAP_GLOBAL_OPTIONS
- ~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``{}``
- A dictionary of options to pass to ``ldap.set_option()``. Keys are
- ``ldap.OPT_*`` constants.
- .. _AUTH_LDAP_GROUP_SEARCH:
- AUTH_LDAP_GROUP_SEARCH
- ~~~~~~~~~~~~~~~~~~~~~~
- Default: ``None``
- An :class:`~django_auth_ldap.config.LDAPSearch` object that finds all LDAP
- groups that users might belong to. If your configuration makes any references to
- LDAP groups, this and :ref:`AUTH_LDAP_GROUP_TYPE` must be set.
- .. _AUTH_LDAP_GROUP_TYPE:
- AUTH_LDAP_GROUP_TYPE
- ~~~~~~~~~~~~~~~~~~~~
- Default: ``None``
- An :class:`~django_auth_ldap.config.LDAPGroupType` instance describing the type
- of group returned by :ref:`AUTH_LDAP_GROUP_SEARCH`.
- .. _AUTH_LDAP_MIRROR_GROUPS:
- AUTH_LDAP_MIRROR_GROUPS
- ~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``False``
- If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` will mirror a user's
- LDAP group membership in the Django database. Any time a user authenticates, we
- will create all of his LDAP groups as Django groups and update his Django group
- membership to exactly match his LDAP group membership. If the LDAP server has
- nested groups, the Django database will end up with a flattened representation.
- .. _AUTH_LDAP_PROFILE_ATTR_MAP:
- AUTH_LDAP_PROFILE_ATTR_MAP
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``{}``
- A mapping from user profile field names to LDAP attribute names. A user's
- profile will be populated from his LDAP attributes at login.
- .. _AUTH_LDAP_REQUIRE_GROUP:
- AUTH_LDAP_REQUIRE_GROUP
- ~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``None``
- The distinguished name of a group that a user must belong to in order to
- successfully authenticate.
- .. _AUTH_LDAP_SERVER_URI:
- AUTH_LDAP_SERVER_URI
- ~~~~~~~~~~~~~~~~~~~~
- Default: ``ldap://localhost``
- The URI of the LDAP server. This can be any URI that is supported by your
- underlying LDAP libraries.
- .. _AUTH_LDAP_START_TLS:
- AUTH_LDAP_START_TLS
- ~~~~~~~~~~~~~~~~~~~
- Default: ``False``
- If ``True``, each connection to the LDAP server will call start_tls to enable
- TLS encryption over the standard LDAP port. There are a number of configuration
- options that can be given to :ref:`AUTH_LDAP_GLOBAL_OPTIONS` that affect the
- TLS connection. For example, ``ldap.OPT_X_TLS_REQUIRE_CERT`` can be set to
- ``ldap.OPT_X_TLS_NEVER`` to disable certificate verification, perhaps to allow
- self-signed certificates.
- .. _AUTH_LDAP_USER_ATTR_MAP:
- AUTH_LDAP_USER_ATTR_MAP
- ~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``{}``
- A mapping from :class:`~django.contrib.auth.models.User` field names to LDAP
- attribute names. A users's :class:`~django.contrib.auth.models.User` object will
- be populated from his LDAP attributes at login.
- .. _AUTH_LDAP_USER_DN_TEMPLATE:
- AUTH_LDAP_USER_DN_TEMPLATE
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``None``
- A string template that describes any user's distinguished name based on the
- username. This must contain the placeholder ``%(user)s``.
- .. _AUTH_LDAP_USER_FLAGS_BY_GROUP:
- AUTH_LDAP_USER_FLAGS_BY_GROUP
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Default: ``{}``
- A mapping from boolean :class:`~django.contrib.auth.models.User` field names to
- distinguished names of LDAP groups. The corresponding field is set to ``True``
- or ``False`` according to whether the user is a member of the group.
- .. _AUTH_LDAP_USER_SEARCH:
- AUTH_LDAP_USER_SEARCH
- ~~~~~~~~~~~~~~~~~~~~~
- Default: ``None``
- An :class:`~django_auth_ldap.config.LDAPSearch` object that will locate a user
- in the directory. The filter parameter should contain the placeholder
- ``%(user)s`` for the username. It must return exactly one result for
- authentication to succeed.
- Configuration
- -------------
- .. module:: django_auth_ldap.config
- .. class:: LDAPSearch
- .. method:: __init__(base_dn, scope, filterstr='(objectClass=*)')
- * ``base_dn``: The distinguished name of the search base.
- * ``scope``: One of ``ldap.SCOPE_*``.
- * ``filterstr``: An optional filter string (e.g. '(objectClass=person)').
- In order to be valid, ``filterstr`` must be enclosed in parentheses.
- .. class:: LDAPGroupType
- The base class for objects that will determine group membership for various
- LDAP grouping mechanisms. Implementations are provided for common group
- types or you can write your own. See the source code for subclassing notes.
-
- .. method:: __init__(name_attr='cn')
-
- By default, LDAP groups will be mapped to Django groups by taking the
- first value of the cn attribute. You can specify a different attribute
- with ``name_attr``.
- .. class:: PosixGroupType
- A concrete subclass of :class:`~django_auth_ldap.config.LDAPGroupType` that
- handles the ``posixGroup`` object class. This checks for both primary group
- and group membership.
- .. method:: __init__(name_attr='cn')
- .. class:: MemberDNGroupType
- A concrete subclass of
- :class:`~django_auth_ldap.config.LDAPGroupType` that handles grouping
- mechanisms wherein the group object contains a list of its member DNs.
-
- .. method:: __init__(member_attr, name_attr='cn')
-
- * ``member_attr``: The attribute on the group object that contains a
- list of member DNs. 'member' and 'uniqueMember' are common examples.
- .. class:: NestedMemberDNGroupType
- Similar to :class:`~django_auth_ldap.config.MemberDNGroupType`, except this
- allows groups to contain other groups as members. Group hierarchies will be
- traversed to determine membership.
- .. method:: __init__(member_attr, name_attr='cn')
-
- As above.
- .. class:: GroupOfNamesType
- A concrete subclass of :class:`~django_auth_ldap.config.MemberDNGroupType`
- that handles the ``groupOfNames`` object class. Equivalent to
- ``MemberDNGroupType('member')``.
- .. method:: __init__(name_attr='cn')
- .. class:: NestedGroupOfNamesType
- A concrete subclass of
- :class:`~django_auth_ldap.config.NestedMemberDNGroupType` that handles the
- ``groupOfNames`` object class. Equivalent to
- ``NestedMemberDNGroupType('member')``.
- .. method:: __init__(name_attr='cn')
- .. class:: GroupOfUniqueNamesType
- A concrete subclass of :class:`~django_auth_ldap.config.MemberDNGroupType`
- that handles the ``groupOfUniqueNames`` object class. Equivalent to
- ``MemberDNGroupType('uniqueMember')``.
- .. method:: __init__(name_attr='cn')
- .. class:: NestedGroupOfUniqueNamesType
- A concrete subclass of
- :class:`~django_auth_ldap.config.NestedMemberDNGroupType` that handles the
- ``groupOfUniqueNames`` object class. Equivalent to
- ``NestedMemberDNGroupType('uniqueMember')``.
- .. method:: __init__(name_attr='cn')
- .. class:: ActiveDirectoryGroupType
- A concrete subclass of :class:`~django_auth_ldap.config.MemberDNGroupType`
- that handles Active Directory groups. Equivalent to
- ``MemberDNGroupType('member')``.
- .. method:: __init__(name_attr='cn')
- .. class:: NestedActiveDirectoryGroupType
- A concrete subclass of
- :class:`~django_auth_ldap.config.NestedMemberDNGroupType` that handles
- Active Directory groups. Equivalent to
- ``NestedMemberDNGroupType('member')``.
- .. method:: __init__(name_attr='cn')
- Backend
- -------
- .. module:: django_auth_ldap.backend
- .. class:: LDAPBackend
- :class:`~django_auth_ldap.backend.LDAPBackend` has one method that may be
- called directly and several that may be overridden in subclasses.
- .. method:: populate_user(username)
- Populates the Django user for the given LDAP username. This connects to
- the LDAP directory with the default credentials and attempts to populate
- the indicated Django user as if they had just logged in.
- :ref:`AUTH_LDAP_ALWAYS_UPDATE_USER` is ignored (assumed ``True``).
- .. method:: get_or_create_user(self, username, ldap_user)
- Given a username and an LDAP user object, this must return the
- associated Django User object. The ``username`` argument has already
- been passed through
- :meth:`~django_auth_ldap.backend.LDAPBackend.ldap_to_django_username`.
- You can get information about the LDAP user via ``ldap_user.dn`` and
- ``ldap_user.attrs``. The return value must be the same as
- ``User.objects.get_or_create()``: a (User, created) two-tuple.
- The default implementation simply calls ``User.objects.get_or_create()``
- with the username. Subclasses are welcome to associate LDAP users to
- Django users any way they like.
- .. method:: ldap_to_django_username(username)
-
- Returns a valid Django username based on the given LDAP username (which
- is what the user enters). By default, ``username`` is returned
- unchanged. This can be overriden by subclasses.
- .. method:: django_to_ldap_username(username)
- The inverse of
- :meth:`~django_auth_ldap.backend.LDAPBackend.ldap_to_django_username`.
- If this is not symmetrical to
- :meth:`~django_auth_ldap.backend.LDAPBackend.ldap_to_django_username`,
- the behavior is undefined.
- License
- =======
- Copyright (c) 2009, Peter Sagerson
- All rights reserved.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- - Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or
- other materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|