I'm trying to implement an authentication based on a LDAP condition and I can't get my head around on how to achieve this.
My project already uses Django's built-in authentication system, which works great and looks like this:
# urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views
from coffee_app.forms import LoginForm
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('coffee_app.urls')),
url(r'^login/$', views.login, {'template_name': 'login.html', 'authentication_form': LoginForm}, name='login'),
url(r'^logout/$', views.logout, {'next_page': '/login'}, name='logout'),
]
# forms.py
from django.contrib.auth.forms import AuthenticationForm
from django import forms
class LoginForm(AuthenticationForm):
username = forms.CharField(label="Username", max_length=32,
widget=forms.TextInput(attrs={
'class': 'form-control',
'name': 'username'
}))
password = forms.CharField(label="Password", max_length=20,
widget=forms.PasswordInput(attrs={
'class': 'form-control',
'name': 'password'
}))
<!--login.html (relevant part)-->
<form class="form-horizontal" action="{% url 'login' %}" method="post" id="contact_form">
{% csrf_token %}
<fieldset>
<div class="form-group">
<label class="col-md-4 control-label">{{ form.username.label_tag }}</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
{{ form.username }}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" >{{ form.password.label_tag }}</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
{{ form.password }}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label"></label>
<div class="col-md-4 text-center">
<br>
<button value="login" type="submit" class="btn btn-warning" >
LOG IN
<span class="glyphicon glyphicon-send"></span>
</button>
</div>
</div>
</fieldset>
<input type="hidden" name="next" value="{{ next }}"/>
</form>
Now, what I'm trying to do, is to verify whether a user exists in LDAP or not, before getting to the initial Django auth:
from ldap3 import Server, Connection, ALL, NTLM
server = Server('server here', get_info=ALL, use_ssl=True)
conn = Connection(server,
user='DOMAIN\\username',
password='password',
authentication=NTLM)
print(conn.bind())
If conn.bind()
returns True
, I'd like to go further to Django's built-in authentication system and authenticate the user. Unfortunately, I don't know where / how to add this step in order to achieve this.
Some views look like this:
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
@login_required(login_url="login/")
def home(request):
return render(request, "home.html")
@login_required(login_url="login/")
def activity_report_page(request):
return render(request, "activity_report.html")
...
And their urls:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'report$', views.activity_report_page, name='activity_report')
]
Could someone please point out where should I add the LDAP piece of code so that I can first verify if a user exist there?
PS: I didn't consider using django-auth-ldap
because I don't really need a pure LDAP authentication-based system. Just a simple verification.
You want to customize authentication in Django , where you more specifically want to write an authentication backend . I assume that your project is called 'coffee_site', and you have the app 'coffee_app'. You first want to change coffee_site/settings.py
, and append AUTHENTICATION_BACKENDS = ['coffee_site.auth.LDAP']
to it. After this, you want to make and edit coffee_site/auth.py
. As you said in the question you want to use the default authentication, and so you should inherit from django.contrib.auth.backends.ModelBackend
, you then want to make it so that if conn.bind()
is not True, then you don't use the default authentication, and so you should return None
. This can be implemented with:
from django.contrib.auth.backends import ModelBackend
from ldap3 import Server, Connection, ALL, NTLM
server = Server('server here', get_info=ALL, use_ssl=True)
class LDAP(ModelBackend):
def authenticate(self, *args, **kwargs):
username = kwargs.get('username')
password = kwargs.get('password')
if username is None or password is None:
return None
conn = Connection(server,
user='DOMAIN\\{}'.format(username),
password=password,
authentication=NTLM)
if not conn.bind():
return None
return super().authenticate(*args, **kwargs)
Note : I checked this works on Django's side, but I made no effort to check that the LDAP code works.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.