Mi configuración: Django-3.0, Python-3.8, django_auth_ldap
Tengo un servidor LDAP (Active Directory Server) en mi organización. Estoy creando una aplicación Django que sirve para algunas operaciones para todos los usuarios.
Sé que Django tiene un mecanismo de autenticación de usuario incorporado, pero autentica si los usuarios están presentes en la base de datos del modelo de usuario.
Pero mi requisito es.
Todas las entradas de usuario están en el servidor LDAP (Directorio activo). Usar las credenciales de usuario adecuadas El servidor LDAP me autentica.
Creé una página de inicio de sesión en la aplicación Django 'cuentas' ,
1. cada vez que ingreso el nombre de usuario y la contraseña desde la página de inicio de sesión, debe autenticarse utilizando el servidor LDAP de mi organización.
2. Después de iniciar sesión, debo mantener la sesión para el usuario que inició sesión durante 5 minutos activos. (sesión de autenticación de Django)
Vi que el paquete django_auth_ldap da una idea de mi propósito.
Tengo estos contenidos en settings.py .
import ldap ##Ldap settings AUTH_LDAP_SERVER_URI = "ldap://myldapserver.com" AUTH_LDAP_CONNECTION_OPTIONS = {ldap.OPT_REFERRALS : 0} AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s, OU=USERS,dc=myldapserver, dc=com" AUTH_LDAP_START_TLS = True #Register authentication backend AUTHENTICATION_BACKENDS = [ "django_auth_ldap.backend.LDAPBackend", ]Llamar a autenticarse en views.py .
from django_auth_ldap.backend import LDAPBackend def accounts_login(request): username = "" password = "" if request.method == "POST": username = request.POST.get('username') password = request.POST.get('password') auth = LDAPBackend() user = auth.authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect("/") else: error = "Authentication Failed" return render(request, "accounts/login.html", 'error':error) return render(request, "accounts/login.html")Pero el uso del método anterior siempre falla en la autenticación con el servidor LDAP.
Si llamo usando python normal simple_bind_s(), la autenticación funciona bien en el mismo servidor LDAP.
import ldap def ldap_auth(username, password): conn = ldap.initialize(myproj.settings.LDAP_AUTH_URI) try: ldap.set_option(ldap.OPT_REFERRALS, 0) #ldap.set_option(ldap.OPT_PROTOCOL_VERSION, 3) conn.simple_bind_s(username, password) except ldap.LDAPError as e: return f'failed to authenticate' conn.unbind_s() return "Success"¿Alguien puede sugerirme que haga que la autenticación LDAPBackend funcione según mis requisitos?
Nota: No tengo permiso de administrador del servidor LDAP.
Así es como lo haría con ldap3 y sin los paquetes django_auth_ldap .
1 - Cree un AuthenticationBackend personalizado en your_app/backends.py :
import logging from ldap3 import Server, Connection from ldap3.core.exceptions import LDAPBindError from django.conf import settings from django.contrib.auth import get_user_model logger = logging.getLogger(__name__) UserModel = get_user_model() class LDAPBackend: def authenticate(self, request, username=None, password=None, **kwargs): # set username to lowercase for consistency username = username.lower() # get the bind client to resolve DN logger.info('authenticating %s' % username) # set your server server = Server(settings.LDAP_HOST, get_info=ALL) try: conn = Connection(server, f"{username}@{settings.LDAP_DOMAIN}", password=password, auto_bind=True) except LDAPBindError as e: logger.info('LDAP authentication failed') logger.info(e) return None user = UserModel.objects.update_or_create(username=username) return user def get_user(self, user_id): try: return UserModel._default_manager.get(pk=user_id) except UserModel.DoesNotExist: return None 2 - Declare LDAPBackend como su backend de autenticación en settings.py
AUTHENTICATION_BACKENDS = [ 'your_app.backends.LDAPBackend', 'django.contrib.auth.backends.ModelBackend' ]Esto le permite usar la función nativa de django para la autenticación y funciona con el administrador.
Para que la sesión solo funcione durante 5 minutos, agregue esta configuración a su archivo settings.py :
SESSION_COOKIE_AGE = 5 * 60Déjame saber si funciona para ti.