Quidquid latine dictum sit, altum sonatur. Quod erat demonstrandum.
RSS icon Email icon Home icon
  • How to allow Django to authenticate against Active Directory

    Posted on October 19th, 2007 Jordan 2 comments

    I used PyWin32 on a Django 0.96 instance after struggling and giving up on using python-ldap. This doesn’t query any of the AD user object’s attributes; it just lets them log in to the Django site and creates a Django user object for them.

    Thanks to Benji York for posting the code that talks to Active Directory using PyWin32 to the python mailing list.

    from django.conf import settings
    from django.contrib.auth.models import User, check_password
    from win32security import LogonUser, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT
    import pywintypes
    class ADBackend:
    """
    Authenticates against Active Directory.
    """
    def attempt_ad_login(self, username, password):
    try:
    handle=LogonUser(username, None, password,
    LOGON32_LOGON_NETWORK,
    LOGON32_PROVIDER_DEFAULT)
    # We're not going to use the handle, just seeing if we can get it.
    handle.Close()
    return True
    except pywintypes.error, e:
    # Because of the sheer number of Windows-specific errors that can
    # occur here, we have to assume any of them mean that the
    # credentials were not valid.
    return False
    def authenticate(self, username=None, password=None):
    if self.attempt_ad_login(username, password):
    try:
    user = User.objects.get(username=username)
    except User.DoesNotExist:
    # Create a new user. This password will not be checked during login, so it doesn't matter.
    user = User(username=username, password='dummy password')
    # Comment or uncomment these as appropriate.
    user.is_staff = True
    #user.is_superuser = True
    user.save()
    return user
    else:
    return None
    def get_user(self, user_id):
    try:
    return User.objects.get(pk=user_id)
    except User.DoesNotExist:
    return None

    Save this to a file such as “ADBackend.py” in the same path as your application, then add the following to your settings.py, replacing mysite and myapp to match your Django site and application:

    AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'mysite.myapp.ADBackend.ADBackend'
    )