【django】嵌入LDAP心得

涉及第三方库:

  • pyldap(如果部署在windows上需要用whl包来安装比较顺利,参考pyldap-2.4.28-cp35-cp35m-win_amd64.whl)
  • django-auth-ldap

修改setting文件

  • 需要导入2个库

    1
    2
    import ldap
    from django_auth_ldap.config import LDAPSearch
  • 添加配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    LOGIN_URL = '/login.html'
    AUTHENTICATION_BACKENDS = (
    # 'django_auth_ldap.backend.LDAPBackend',
    'dashboard.myldapbackend.MYLDAPBackend',
    # 'django.contrib.auth.backends.ModelBackend',
    )
    AUTH_LDAP_SERVER_URI = 'ldap://127.0.0.1'
    AUTH_LDAP_BIND_DN = 'cn=Manager,dc=abc,dc=com'
    AUTH_LDAP_BIND_PASSWORD = "123456"
    AUTH_LDAP_USER_SEARCH = LDAPSearch("dc=abc,dc=com", ldap.SCOPE_SUBTREE, "(cn=%(user)s)")
    AUTH_LDAP_ALWAYS_UPDATE_USER = False
  • 其中,“AUTHENTICATION_BACKENDS”中,如果不需要将user信息写入本地数据库/文件的话,则需要改造“LDAPBackend”文件,例如上面的’dashboard.myldapbackend.MYLDAPBackend’参考,改造内容如下:

修改class LDAPBackend(object): 为class MYLDAPBackend(object):

1
2
3
4
5
6
7
8
9
def get_user_model(self):
"""
By default, this will return the model class configured by
AUTH_USER_MODEL. Subclasses may wish to override it and return a proxy
model.
"""
# 注释 get_user_model(),改为直接return User
return User
# return get_user_model()
1
2
3
4
5
6
7
8
9
10
11
12
13
def get_user(self, user_id):
user = None
try:
# user = self.get_user_model().objects.get(pk=user_id)
# 注释上面的,生成user对象
user = self.get_user_model()(username=username,email=mail)
_LDAPUser(self, user=user) # This sets user.ldap_user
except ObjectDoesNotExist:
pass
return user
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def get_or_create_user(self, username, ldap_user):
"""
This must return a (User, created) 2-tuple for the given LDAP user.
username is the Django-friendly username of the user. ldap_user.dn is
the user's DN and ldap_user.attrs contains all of their LDAP attributes.
"""
# model = self.get_user_model()
# username_field = getattr(model, 'USERNAME_FIELD', 'username')
# kwargs = {
# username_field + '__iexact': username,
# 'defaults': {username_field: username.lower()}
# }
# return model.objects.get_or_create(**kwargs)
# 注释上面的,改为下面的
model = self.get_user_model()
mail = "xxx@xxx.com"
user = model(username=username,email=mail)
return user,False

修改跟setting同目录的views文件,参考如下:

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from functools import wraps
from django.http import HttpResponse,HttpResponseRedirect
from django.shortcuts import render_to_response, render, redirect
from django.contrib.auth import authenticate, login, logout
def myLoginCheck(view_func):
def _wrapped_view(request, *args, **kwargs):
user = request.session.get('username', None)
if user and request.user:
return view_func(request, *args, **kwargs)
else:
return redirect('/?next=' + request.get_full_path())
return _wrapped_view
@myLoginCheck
def Home(request):
return render(request, 'index.html')
def login_page(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
next = request.POST.get('next', '/home')
user = authenticate(username=username, password=password)
if user is not None:
# login(request, user)
# Redirect to a success page.
print(request.session)
request.user = user
print("user is :", request.user.username)
request.session['username'] = username
request.session.set_expiry(7*24*60*60)
print("login success", next)
return HttpResponseRedirect(next)
else:
return render(request, 'page_403.html', locals())
if request.method == 'GET':
next = request.GET.get('next', '/home')
kwvars = {
'next':next,
}
return render(request, 'login.html', kwvars)
@myLoginCheck
def logout_os(request):
del request.session['username']
request.session['username'] = None
request.session.flush()
request.user = None
logout(request)
return HttpResponseRedirect('/')

修改跟setting同目录的urls文件,参考如下:

1
2
3
4
5
6
7
# 列表里第一行默认加载登录页面
urlpatterns = [
url(r'^$', views.login_page),
url(r'^home', views.Home),
url(r'^login.html', views.login_page, name="login"),
url(r'^logout.html', views.logout_os, name="logout"),
]