Django, LDAP and SSL

August 14, 2012 - IT


  • Users can log in using LDAP only
  • Admin can log in with or without LDAP
  • Only username and password are verified, nothing more
  • First, we need openldap and python-ldap packages.

I have created my own authenticate backend based on django.contrib.auth.backends.ModelBackend.

# coding=utf-8
import ldap
import logging
from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend

logger = logging.getLogger('helper')

class LdapBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        if username:
            All usernames in database are lowercase.
            username = username.lower()
            user = User.objects.get(username=username)
            if user.has_usable_password():
                User can log in without LDAP.
                if user.check_password(password):
                    return user
                LDAP only.
                ldap_address = 'IP:PORT'
                domain = ''
                l = ldap.initialize('ldaps://%s' % ldap_address)
                l.set_option(ldap.OPT_REFERRALS, 0)
                l.set_option(ldap.OPT_TIMEOUT, 5)
                l.set_option(ldap.OPT_NETWORK_TIMEOUT, 5)
                l.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
                l.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
                l.set_option(ldap.OPT_X_TLS_DEMAND, True)
                l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
                    l.simple_bind_s('%[email protected]%s' % (username.encode('utf-8'),
                    return user
                except ldap.INVALID_CREDENTIALS as e:
                    Wrong username or password.
                    return None
                except Exception as e:
                    It has not happened yet. ;-)
                    logger.error(u'LDAP Error. User %s. %s' % (username,
                    return None
        except User.DoesNotExist:
            return None

Set new authentication backend in

AUTHENTICATION_BACKENDS = ('project.ldapbackend.LdapBackend', )

Last thing. I have set unusable password while user is creating. One admin (me). The rest have to use LDAP. Otherwise I can set a password for user manually.

from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def createUserProfile(sender, instance, created, **kwargs):
    if created:
        profile, created = UserProfile.objects.get_or_create(user=instance)
        if created:

Improvements? ;-)