django使用LDAP验证的方法示例


Posted in Python onDecember 10, 2018

1.安装Python-LDAP(python_ldap-2.4.25-cp27-none-win_amd64.whl)pip install python_ldap-2.4.25-cp27-none-win_amd64.whl

2.安装django-auth-ldap(django-auth-ldap-1.2.8.tar.gz)(下载:https://pypi.python.org/pypi/django-auth-ldap),Windows下也可以使用 python setup.py install

安装成功后运行命令,运行成功表示安装成功

from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion, GroupOfNamesType

3.配置settings.py,增加如下:

参考:https://pypi.python.org/pypi/django-auth-ldap/1.2.1说明文档

# -*- coding: UTF-8 -*-

import ldap
from django_auth_ldap.config import LDAPSearch #导入LDAP model

AUTHENTICATION_BACKENDS = ( 
  'django_auth_ldap.backend.LDAPBackend', #配置为先使用LDAP认证,如通过认证则不再使用后面的认证方式
  'django.contrib.auth.backends.ModelBackend', 
) 

AUTH_LDAP_SERVER_URI = 'ldap://192.168.200.20:389'
AUTH_LDAP_BIND_DN = 'CN=test01,OU=ServerAdmin,DC=uu,DC=yyy,DC=com'
AUTH_LDAP_BIND_PASSWORD = '123456' 
OU = unicode('OU=中文名,DC=uu,DC=yyy,DC=com', 'utf8') #限制哪个OU中的用户可以进行AD认证。如果OU中包含有中文字符,则需要这样写,否则会出现ascii无法识别的报错(UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position)
# OU0 = 'OU=ServerAdmin,DC=uxin,DC=youxinpai,DC=com'
# OU = unicode('OU=优,DC=uxin,DC=youxinpai,DC=com', 'utf8')
# OU1 = u'OU=优,DC=uxin,DC=youxinpai,DC=com'
# OU2 = u'OU=\u4f18,DC=uxin,DC=youxinpai,DC=com'
# OU == OU1 == OU2 #返回True
#检索单个OU
AUTH_LDAP_USER_SEARCH = LDAPSearch(OU, ldap.SCOPE_SUBTREE, "(&(objectClass=person)(sAMAccountName=%(user)s))")

# 检索多个OU:
# AUTH_LDAP_USER_SEARCH = LDAPSearchUnion( 
#   LDAPSearch("ou=user,ou=ou1,ou=ou,dc=cn,dc=com",ldap.SCOPE_SUBTREE, "(&(objectClass=user)(sAMAccountName=%(user)s))"), 
#   LDAPSearch("ou=user,ou=ou2,ou=ou,dc=cn,dc=com",ldap.SCOPE_SUBTREE, "(&(objectClass=user)(sAMAccountName=%(user)s))"), 
# ) 

#将账号的姓、名、邮件地址保存到django的auth_user表中,在admin后台可以看到
AUTH_LDAP_USER_ATTR_MAP = { 
  "first_name": "givenName",
  "last_name": "sn",
  "email": "mail"
}

同步用户组信息:

当用户登录后,如果用户属于某个组,则会将该组同步到auth_group表中,之后在admin后台可以对该组进行权限设置,之后同属于该组的用户在登录后则具有相应的权限。

当一个用户不再属于某个组,该组也不会被自动删掉,在admin后台手工删掉即可。

from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion, GroupOfNamesType 

AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn") #返回的组的类型,并用来判断用户与组的从属关系

OUg = unicode('OU=安全组,DC=uu,DC=yyy,DC=com', 'utf8')
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(OUg,ldap.SCOPE_SUBTREE, "(objectClass=group)" ) #搜索某个OU下组信息
 
AUTH_LDAP_MIRROR_GROUPS = True #导入用户的组信息,在用户登录的时候把用户的域组关系同步过来。每次用户登录时,都会把用户的组关系删除,重新从ldap中进行同步(解决办法参考后面)

AUTH_LDAP_ALWAYS_UPDATE_USER = True #是否同步LDAP修改

4.编辑views.py,当用户通过认证后,还可以使用django自带的用户认证、权限设置模块:

from django.contrib.auth import authenticate,login as auth_login,logout as auth_logout
from django.contrib.auth.models import User

@csrf_exempt
def loginauth(request):
  user_loggedin='Guest'
  errors_list=[]
  if request.method == 'POST':
    print 'pp: ',request.POST.get('name'),request.POST.get('password')
    name = request.POST.get('name')
    password = request.POST.get('password')
    user = authenticate(username=name, password=password)
    print 'authuser',user
    if user is not None:
      auth_login(request,user)
      uu=request.user
      u=User.objects.get(username=uu)return HttpResponseRedirect("../check_dict")
    
  context={'errors_list':errors_list,'user_loggedin':user_loggedin}
  return render(request,'aptest/loginauth.html',context)

auth_user表结构:

django使用LDAP验证的方法示例 

admin后台显示:

django使用LDAP验证的方法示例 

解决中文乱码问题(有问题可以试下):

在安装django-auth-ldap-1.2.8.tar之前,先在里面的.py中加上'# -*- coding: UTF-8 -*-'

修改C:\Python27\Lib\site-packages\Django-1.8.4-py2.7.egg\django\conf\global_settings.py和修改settings.py,如下:

TIME_ZONE = 'Asia/Shanghai'
LANGUAGE_CODE = 'zh-hans'

======================== ========================

LDAP用户验证基本原理

每个用户在LDAP系统中有一个唯一的DN值,例如配置文件中默认的admin用户在LDAP中的DN值是uid=admin,ou=system,dc=eoncloud,dc=com, 其中eoncloud.com是域名,system是组名,admin是用户名,有些LDAP用cn而不是uid来生成DN,在这种系统中admin的DN看起来像这样cn=admin,ou=system,dc=eoncloud,dc=com,无论是uid还是cn或是别的前缀,django-ldap-auth都是用dn来验证用户和获取用户信息的.

假设用户输入的帐号及密码是: test, password.

django-auth-ldap有2个方式来获取用户的DN

  1. 使用AUTH_LDAP_USER_DN_TEMPLATE提供的模板生成DN.如uid=%(user)s,ou=users,dc=eoncloud,dc=com, 其中%(user)s会被替换成用户名,这样最终的DN就是uid=test,ou=users,dc=eonclooud,dc=com.
  2. 使用AUTH_LDAP_GROUP_SEARCH.如果没有配置AUTH_LDAP_USER_DN_TEMPLATE,那么django-auth-ldap会使用AUTH_LDAP_BIND_DN和AUTH_LDAP_BIND_PASSWORD提供的dn与密码根据AUTH_LDAP_GROUP_SEARCH提供的查询条件去查找test用户,如果查不到,验证失败,如果查到用户,就使用返回的数据生成test的DN. 
  3. 利用第2步生成DN值与密码尝试访问LDAP系统,如果访问成功,则验证共过,否则验证失败.

基本配置

  1. AUTH_LDAP_SERVER_URI. LDAP系统的地址及端口号
  2. AUTH_LDAP_BIND_DN, AUTH_LDAP_BIND_PASSWORD. 查找用户及相关信息的默认用户信息
  3. AUTH_LDAP_USER_SEARCH. 第一个参数指指定询目录,第三个参数是过滤条件,过滤条件可以很复杂,有需要请查看相关文档.
  4. AUTH_LDAP_USER_DN_TEMPLATE. 用户DN模板,配置该参数后django-auth-ldap会用生成的DN配合密码验证该用户.
  5. AUTH_LDAP_USER_ATTR_MAP. LDAP与User model映射.
  6. AUTH_LDAP_ALWAYS_UPDATE_USER. 是否同步LDAP修改.

用户组配置

如果需要,django-auth-ldap可以从ldap系统获取用户的组信息,也可以限定某个组里的用户访问,或者阻止某个组里的用户访问,无论是使用哪个功能都需要先配置组类型AUTH_LDAP_GROUP_TYPE及AUTH_LDAP_GROUP_SEARCH, 因为LDAP里组的种类非常多,具体信息请查询相关资料.

AUTH_LDAP_GROUP_TYPE

  • 值类型: LDAPGroupType的子类实例.LDAPGroupType有2个初始化参数:member_attr, name_attr.member_attr是组成员的属性名, name_attr是组名称的属性名.
  • 作用: AUTH_LDAP_GROUP_SEARCH返回的组的类型,并用来判断用户与组的从属关系

AUTH_LDAP_GROUP_SEARCH

  • 值类型: LDAPSearch实例.
  • 作用: 用户组的查询条件

AUTH_LDAP_REQUIRE_GROUP

  • 值类型: 组的DN
  • 作用: 只有指定组的用户可以访问

AUTH_LDAP_DENY_GROUP指定的

  • 值类型: 组的DN
  • 作用: 禁止指定组的用户访问

AUTH_LDAP_MIRROR_GROUPS

  • 值类型: bool值
  • 作用: 导入用户的组信息

AUTH_LDAP_MIRROR_GROUPS=True 这个参数是为了在用户登录的时候把用户的域组关系也获取并记录下来。不过开启这个参数会带来另外一个问题:每次用户登录时,都会把用户的组关系删除,重新从ldap中进行同步。由于我们的系统中除了域组还有些自定义的组关系,这样一来自定义组的用户关系就不能持久保留了。按照我们的需求,其实只希望在用户第一次登录的时候同步组关系,以后的登录并不需要。这个需求可以通过对django-auth-ldap的源码(backend.py)进行微调来实现。

backend.py源码:

def _get_or_create_user(self, force_populate=False): 
...
...
  if self.settings.MIRROR_GROUPS: 
    self._mirror_groups() 

#修改为如下,然后重新安装django-auth-ldap-1.2.8.tar,重启WEB重新验证即可。
  if self.settings.MIRROR_GROUPS and created: 
    self._mirror_groups()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python简单实现计算过期时间的方法
Jun 09 Python
python ftp 按目录结构上传下载的实现代码
Sep 12 Python
详解python--模拟轮盘抽奖游戏
Apr 12 Python
Python实现的远程文件自动打包并下载功能示例
Jul 12 Python
python tkinter实现彩球碰撞屏保
Jul 30 Python
利用Python产生加密表和解密表的实现方法
Oct 15 Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
Dec 11 Python
Cython编译python为so 代码加密示例
Dec 23 Python
什么是Python中的顺序表
Jun 02 Python
python和php哪个容易学
Jun 19 Python
PyCharm2020最新激活码+激活码补丁(亲测最新版PyCharm2020.2激活成功)
Nov 25 Python
关于Python中*args和**kwargs的深入理解
Aug 07 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
Dec 10 #Python
python文件拆分与重组实例
Dec 10 #Python
Python对excel文档的操作方法详解
Dec 10 #Python
使用python进行拆分大文件的方法
Dec 10 #Python
python使用udp实现聊天器功能
Dec 10 #Python
Python面向对象之类和对象实例详解
Dec 10 #Python
详解Django-auth-ldap 配置方法
Dec 10 #Python
You might like
《星际争霸2》终章已出 RTS时代宣告终结
2017/02/07 星际争霸
并发下常见的加锁及锁的PHP具体实现代码
2010/10/12 PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
2015/12/31 PHP
php+iframe 实现上传文件功能示例
2020/03/04 PHP
用php实现分页效果的示例代码
2020/12/10 PHP
JavaScript和JQuery的鼠标mouse事件冒泡处理
2015/06/19 Javascript
js实现带有介绍的Select列表菜单实例
2015/08/18 Javascript
分享纯手写漂亮的表单验证
2015/11/19 Javascript
基于javascript实现彩票随机数生成(简单版)
2020/04/17 Javascript
ECMAScript6快速入手攻略
2016/07/18 Javascript
BootStrap中的Fontawesome 图标
2017/05/25 Javascript
js实现控制文件拖拽并获取拖拽内容功能
2018/02/17 Javascript
Vuejs开发环境搭建及热更新【推荐】
2018/09/07 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
2018/09/14 Javascript
详解适配器在JavaScript中的体现
2018/09/28 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
2019/01/27 jQuery
JavaScript简易计算器制作
2020/01/17 Javascript
vue实现点击按钮“查看详情”弹窗展示详情列表操作
2020/09/09 Javascript
[01:00:22]DOTA2-DPC中国联赛定级赛 LBZS vs Magma BO3第三场 1月10日
2021/03/11 DOTA
python使用循环实现批量创建文件夹示例
2014/03/25 Python
python打开使用的方法
2019/09/30 Python
pytorch实现onehot编码转为普通label标签
2020/01/02 Python
将tensorflow模型打包成PB文件及PB文件读取方式
2020/01/23 Python
python GUI库图形界面开发之PyQt5状态栏控件QStatusBar详细使用方法实例
2020/02/28 Python
Python3 selenium 实现QQ群接龙自动化功能
2020/04/17 Python
python接口自动化框架实战
2020/12/23 Python
CSS 3.0文字悬停跳动特效代码
2020/10/26 HTML / CSS
使用html5 canvas绘制圆环动效
2019/06/03 HTML / CSS
什么是继承
2013/12/07 面试题
教学大赛获奖感言
2014/01/15 职场文书
仓管员岗位责任制
2014/02/19 职场文书
部门年终奖分配方案
2014/05/07 职场文书
司法局火灾防控方案
2014/06/05 职场文书
2014年大学班级工作总结
2014/11/14 职场文书
2016大学生诚信考试承诺书
2016/03/25 职场文书
AngularJS实现多级下拉框
2022/03/25 Javascript