I am new to Django and have been assigned the task of implementing a user authentication system with LDAP as the backend. I guess the documentation assumes that the end developer has enough experience in Django to be able to understand and implement such a system. This is where I fail to understand how to implement a simple django application with LDAP based authentication. Here is what I have understood so far:
Only posting the changes to a file:
settings.py .... import ldap from django_auth_ldap.config import LDAPSearch AUTH_LDAP_SERVER_URI = "ldap://<my url>" AUTHENTICATION_BACKENDS = ('django_auth_ldap.backend.LDAPBackend') AUTH_LDAP_CONNECTION_OPTIONS = { ldap.OPT_REFERRALS: 0 } MIDDLEWARE_CLASSES = ( .... 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', ... ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', .... )
auth.html
<html> <head> <title>Login</title> </head> <body> {{state}} <form action="" method="post"> {% csrf_token %} Email address: <input type="text" name="email" value="{{ email }}" /> Password: <input type="password" name="password" value="" /> <input type="submit" value="Log in" /> </form> </body> </html>
models.py:
??
views.py:
from django.shortcuts import render_to_response from django.contrib.auth import authenticate, login from django.template import RequestContext def login_user(request): username = password = "" state = "" if request.POST: username = request.POST.get('username') password = request.POST.get('password') print username, password user = authenticate(username=username, password=password) if user is not None: login(request, user) state = "Valid account" else: state = "Inactive account" return render_to_response('auth_user/auth.html', RequestContext(request, {'state': state, 'username': username}))
What I am not able to understand?
1> I am pretty sure I would have to implement a function in views.py
to get the POST
values for email
and password
and validate it, e.g: [SO]. The documentation specifies to either implement a Search/Bind or Direct Bind. Why? If the views.py
would contain the actual piece of authentication code, what is the code doing specified in the documentation?
2> If the views.py
would perform the actual auth, then why do we need the variable specified in the documentation?
3> The author has done a great job with the library, but the documentation does not provide with a simple barebones example of how to implement the entire authentication system with LDAP. Can anyone please point to such a resource, if it exists? It is not easy to understand the files that need to be added/modified to implement such a system.
The Django authentication system handles both authentication and authorization. Briefly, authentication verifies a user is who they claim to be, and authorization determines what an authenticated user is allowed to do. Here the term authentication is used to refer to both tasks.
In order to use LDAP with Python we need to import the Server and the Connection object, and any additional constant we will use in our LDAP. As you might remember from the LDAP Protocol diagram the authentication operation is called Bind.
LDAP authentication involves verifying provided usernames and passwords by connecting with a directory service that uses the LDAP protocol. Some directory-servers that use LDAP in this manner are OpenLDAP, MS Active Directory, and OpenDJ.
This page might have what you are looking for: https://pypi.python.org/pypi/django-auth-ldap concerning the LDAP backend. You are lucky that one exists, so you don't have to code an auth backend yourself :-)
Basically django.contrib.auth.models already has a User object that contains everything you need about the user. So you don't need to create a new models.py.
You just need to authenticate yourself in your views.py, in a login function, using
from django.contrib.auth import authenticate, login user = authenticate(username=request.REQUEST.get('email'), password=request.REQUEST.get('password')) # handle error cases, inactive users, ... login(request, user)
If user is None, then authentication failed. If not, you can explore this object to see what has the backend pulled for you.
Then, you can elect to create another model with User as a foreignKey if you want to keep Preferences linked to this User for this application but nor part of the LDAP.
In this case, you will need:
Models.py
The definition of the data that is important to you based on your application. You are going to pull the user data from the LDAP, and fill up this model with it and other preferences linked to the User:
from django.contrib.auth.models import User class Profile(models.Model): """User profile. Contains some basic configurable settings""" user = models.ForeignKey(User, unique=True) phone_number = models.CharField(max_length=256, blank=True, default='') ...
Views.py
in the login function, if request.method == 'POST', then get_or_create the user profile using the user your just got from authenticate.
profile, profile_is_new = Profile.objects.get_or_create(user=user)
The django-auth-ldap docs are indeed written for developers who are familiar with Django. Also LDAP. If you're starting from scratch, I would recommend taking it one step at a time:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With