With this small authentication module, you can make django use ldap as authentication backend. Documentation and configuration instructions are found in the comments.

http://media.kaarsemaker.net/auth_ldap.py

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Ldap authentication backend for Django. Users are authenticated against
# an ldap server and their django accounts (name, email) are maintained
# automatically.
#
# Configuration is done in settings.py, these are the available settings:
#
# # Where to find the ldap server (optional, default: ldap://localhost)
# AUTH_LDAP_HOST = 'ldap://ldap.kaarsemaker.net'
# # Which ldap groups to mirror in django (optional, default [])
# AUTH_LDAP_GROUPS = ('webadmins','ubuntu')
# # The users must be in any of these groups (optional, default [])
# AUTH_LDAP_FILTER_GROUPS = AUTH_LDAP_GROUPS
# # DN for binding to the server (optional, default anonymous bind)
# #AUTH_LDAP_BINDDN = "cn=admin,dc=kaarsemaker,dc=net"
# #AUTH_LDAP_BINDPW = "TheAdminPassword
# # Base DN for users and groups (required)
# AUTH_LDAP_BASEDN_USER = 'ou=People,dc=kaarsemaker,dc=net'
# AUTH_LDAP_BASEDN_GROUP = 'ou=Group,dc=kaarsemaker,dc=net'
# # Do we need to make the user staff?
# AUTH_LDAP_CREATE_STAFF = True
#
# # If you want LDAP to be your only authentication source, use
# AUTHENTICATION_BACKENDS = ('myproject.auth_ldap.LdapAuthBackend',)
# # If you want to use ldap and fall back to django, use
# AUTHENTICATION_BACKENDS = ('myproject.auth_ldap.LdapAuthBackend',
#                            'django.contrib.auth.backends.ModelBackend')
#
# When using ldap exclusively, the superuser created with ./manage.py 
# cannot log in unless the account also exists in ldap. So either make
# sure the user exists in ldap or give another user superuser rights
# before disabling the builtin authentication.
#
# Make sure all your ldap users have a mail attribute, otherwise this
# module will break.
#
# (c)2008 Dennis Kaarsemaker <dennis@kaarsemaker.net>
# License: Same as django

from django.contrib.auth.models import User, Group
from django.contrib.auth.backends import ModelBackend
from django.conf import settings
import ldap

def _find_dn(ls, username):
    ls.bind_s(getattr(settings, 'AUTH_LDAP_BINDDN', ''),
              getattr(settings, 'AUTH_LDAP_BINDPW', ''))
    res = ls.search_s(settings.AUTH_LDAP_BASEDN_USER, ldap.SCOPE_ONELEVEL,
                      "uid=" + username, [])
    if not len(res):
        return
    return res[0]

def _find_groups(ls, username):
    if not getattr(settings, 'AUTH_LDAP_GROUPS', None) and \
       not getattr(settings, 'AUTH_LDAP_FILTER_GROUPS', None):
        return []
    ls.bind_s(getattr(settings, 'AUTH_LDAP_BINDDN', ''),
              getattr(settings, 'AUTH_LDAP_BINDPW', ''))
    res = ls.search_s(settings.AUTH_LDAP_BASEDN_GROUP, ldap.SCOPE_ONELEVEL,
                      "memberUid=" + username, [])
    return [x[1]['cn'][0] for x in res]

class LdapAuthBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        # Authenticate against ldap
        ls = ldap.initialize(getattr(settings, 'AUTH_LDAP_HOST', 'ldap://localhost'))
        dn, attrs = _find_dn(ls, username)
        if not dn:
            ls.unbind()
            return
        try:
            ls.bind_s(dn, password)
        except ldap.INVALID_CREDENTIALS:
            ls.unbind()
            return

        # Are we allowed to log in
        groups = _find_groups(ls, username)
        if getattr(settings, 'AUTH_LDAP_FILTER_GROUPS', None):
            for group in getattr(settings,'AUTH_LDAP_FILTER_GROUPS',[]):
                if group in groups:
                    break
            else:
                ls.unbind()
                return

        # OK, we've authenticated. Do we exist?
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = User.objects.create_user(username, attrs['mail'][0], password)
            user.is_active = True
            if getattr(settings, 'AUTH_LDAP_BINDPW', False))
                user.is_staff = True
        user.first_name = attrs['givenName'][0]
        user.last_name = attrs['sn'][0]
        user.email = attrs['mail'][0]
        user.password = 'This is an LDAP account'

        # Group manglement
        for group in getattr(settings,'AUTH_LDAP_GROUPS',[]):
            dgroup, created = Group.objects.get_or_create(name=group)
            if created:
                dgroup.save()
            if dgroup in user.groups.all() and group not in groups:
                user.groups.remove(dgroup)
            if dgroup not in user.groups.all() and group in groups:
                user.groups.add(dgroup)

        # Done!
        user.save()
        ls.unbind()
        return user


Laatste wijziging door Dennis Kaarsemaker op 12 August 2008 18:37