Moteur LDAP ¶
See also
Contents
Paramètrage LDAP ¶
# https://github.com/pyldap/pyldap/
import ldap
from django_auth_ldap.config import (
# https://django-auth-ldap.readthedocs.io/en/latest/authentication.html
LDAPSearch,
LDAPSearchUnion,
# https://django-auth-ldap.readthedocs.io/en/latest/groups.html
GroupOfNamesType,
)
...
############# Authentification LDAP avec django-auth-ldap ##############
#
# https://django-auth-ldap.readthedocs.io/en/latest/
#
AUTH_LDAP_SERVER_URI = "ldap://XX.YYY.ZZZ"
# LDAP Search/Bind
AUTH_LDAP_BIND_DN = "cn=apache,cn=users,dc=int,dc=XXX,dc=eu"
AUTH_LDAP_BIND_PASSWORD = "#AAXXXYYYY"
AUTH_LDAP_USER_SEARCH = LDAPSearch(
"ou=users,ou=XXX Technologies,dc=int,dc=XXX,dc=eu",
ldap.SCOPE_SUBTREE,
"(sAMAccountName=%(user)s)",
)
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
"OU=Groups,OU=XXX Technologies,DC=int,DC=XXX,DC=eu",
ldap.SCOPE_SUBTREE,
"(objectClass=group)",
)
# What to do once the user is authenticated
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
}
########### Paramètrage Django pour l'utilisation de LDAP ##############
# https://docs.djangoproject.com/fr/2.1/ref/settings/#std:setting-AUTHENTICATION_BACKENDS
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"accounts.backends.Id3LDAPBackend",
"accounts.backends.Id3AuthBackend",
)
Un moteur LDAP accounts/backends.py ¶
1"""Définition des backends d'authentification.
2
3
4.. seealso::
5
6 - https://docs.djangoproject.com/en/dev/topics/auth/customizing/#authentication-backends
7 - https://docs.djangoproject.com/fr/1.10/topics/auth/customizing/#authentication-backends
8 - https://docs.djangoproject.com/en/dev/ref/contrib/auth/#module-django.contrib.auth.backends
9
10
11
12.. seealso::
13
14 - https://pythonhosted.org/django-auth-ldap/
15 - https://bitbucket.org/psagers/django-auth-ldap/commits/tag/1.2.10
16
17
18"""
19import logging
20
21import django.contrib.auth
22import django_auth_ldap
23import structlog
24from django.contrib.auth import get_backends
25from django.contrib.auth import get_user_model
26from django_auth_ldap.backend import LDAPBackend
27from employes.models import Employe
28
29# https://pythonhosted.org/django-auth-ldap/
30# https://docs.djangoproject.com/en/dev/ref/contrib/auth/#django.contrib.auth.backends.ModelBackend
31# https://docs.djangoproject.com/en/1.10/_modules/django/contrib/auth/
32
33# from django.contrib.auth.backends import ModelBackend
34
35
36logger = logging.getLogger("django_auth_ldap")
37logger.addHandler(logging.StreamHandler())
38logger.setLevel(logging.DEBUG)
39
40
41class Id3LDAPBackend(django_auth_ldap.backend.LDAPBackend):
42 """A custom LDAP authentication backend."""
43
44 def authenticate(self, request=None, username=None, password=None, **kwargs):
45 """Overrides LDAPBackend.authenticate to save user password in django.
46
47 Changement de signature le 2017-06-20
48
49 - def authenticate(self, username, password, **kwargs):
50 + def authenticate(self, request=None, username=None, password=None, **kwargs)
51 """
52
53 logger.info(f"Id3LDAPBackend.authenticate({username})")
54 user = None
55 try:
56 user = LDAPBackend.authenticate(
57 self, username=username, password=password, request=request
58 )
59 logger.info(f"Found user:{user}")
60 try:
61 employe = Employe.objects.get(login=username)
62 if employe.user is None:
63 try:
64 employe.user = user
65 employe.save()
66 except Exception as error:
67 logger.error(f"Can't save {employe}")
68 except Exception as error:
69 logger.error(f"Employe {username} not found:{error}")
70
71 except Exception as error:
72 logger.info(
73 f"Exception in Id3LDAPBackend.authenticate({username}) exception:{error}"
74 )
75
76 # If user has successfully logged, save his password in django database
77 if user:
78 logger.info(f"Id3LDAPBackend.authenticate.set_password")
79 user.set_password(password)
80 logger.info(f"Id3LDAPBackend.authenticate() user.save()")
81 user.save()
82 else:
83 logger.info("User is none")
84
85 return user
86
87 def get_or_create_user(self, username, ldap_user):
88 """Overrides LDAPBackend.get_or_create_user to force from_ldap to True."""
89
90 logger.debug("Id3LDAPBackend.get_or_create_user()")
91 kwargs = {"username": username, "defaults": {"from_ldap": True}}
92 user_model = get_user_model()
93 user = user_model.objects.get_or_create(**kwargs)
94 logger.debug(f"Id3LDAPBackend.get_or_create_user({user})")
95 return user
96
97
98class Id3AuthBackend(django.contrib.auth.backends.ModelBackend):
99 """A custom authentication backend overriding django ModelBackend."""
100
101 @staticmethod
102 def _is_ldap_backend_activated():
103 """Returns True if Id3LDAPBackend is activated."""
104 return Id3LDAPBackend in [b.__class__ for b in get_backends()]
105
106 def authenticate(self, username, password):
107 """Overrides ModelBackend to refuse LDAP users if Id3LDAPBackend is activated."""
108
109 if self._is_ldap_backend_activated():
110 user_model = get_user_model()
111 logger.debug(
112 f"Id3AuthBackend.authenticate({username}/{password}) get_user_model():{user_model}"
113 )
114 try:
115 user = user_model.objects.get(username=username, from_ldap=False)
116 logger.debug(
117 f"Id3AuthBackend.authenticate({username}/{password}) user_model.objects.get({user})"
118 )
119 return user
120 except:
121 logger.debug("Id3AuthBackend.authenticate() return None")
122 return None
123 else:
124 logger.debug("Ldap backend is not activated")
125
126 return user