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异步任务队列示例
Apr 01 Python
在django中使用自定义标签实现分页功能
Jul 04 Python
Python处理命令行参数模块optpars用法实例分析
May 31 Python
在cmder下安装ipython以及环境的搭建
Oct 19 Python
Python+OpenCV感兴趣区域ROI提取方法
Jan 10 Python
利用anaconda保证64位和32位的python共存
Mar 09 Python
python实现kNN算法识别手写体数字的示例代码
Aug 16 Python
python Popen 获取输出,等待运行完成示例
Dec 30 Python
Python socket处理client连接过程解析
Mar 18 Python
Keras框架中的epoch、bacth、batch size、iteration使用介绍
Jun 10 Python
python3.9.1环境安装的方法(图文)
Feb 02 Python
Pytorch中TensorBoard及torchsummary的使用详解
May 12 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
php调用mysql存储过程
2007/02/14 PHP
破解图片防盗链的代码(asp/php)测试通过
2010/07/02 PHP
CI使用Tank Auth转移数据库导致密码用户错误的解决办法
2014/06/12 PHP
php arsort 数组降序排序详细介绍
2016/11/17 PHP
ExtJS4中的requires使用方法示例介绍
2013/12/03 Javascript
解析jQuery的三种bind/One/Live事件绑定使用方法
2013/12/30 Javascript
使用javascript实现json数据以csv格式下载
2015/01/09 Javascript
javascript+HTML5 Canvas绘制转盘抽奖
2020/05/16 Javascript
浅谈jQuery效果函数
2016/09/16 Javascript
基于Vue实现timepicker
2017/04/25 Javascript
WebStorm ES6 语法支持设置&babel使用及自动编译(详解)
2017/09/08 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
2017/11/27 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
基于javascript实现贪吃蛇经典小游戏
2020/04/10 Javascript
解决antd Form 表单校验方法无响应的问题
2020/10/27 Javascript
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
利用Python和OpenCV库将URL转换为OpenCV格式的方法
2015/03/27 Python
python3实现基于用户的协同过滤
2018/05/31 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
2019/08/02 Python
python django生成迁移文件的实例
2019/08/31 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
Python如何使用OS模块调用cmd
2020/02/27 Python
python语音识别指南终极版(有这一篇足矣)
2020/09/09 Python
欧舒丹美国官网:L’Occitane美国
2018/02/23 全球购物
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
2014/09/09 面试题
轻化专业学生实习自我鉴定
2013/09/20 职场文书
房地产销售员的自我评价分享
2013/12/04 职场文书
公司市场专员岗位职责
2014/06/29 职场文书
2015教师见习期工作总结
2014/12/12 职场文书
2014会计年终工作总结
2014/12/20 职场文书
拾金不昧表扬稿大全
2015/05/05 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
2019消防宣传标语!
2019/07/10 职场文书
MySQL安装后默认自带数据库的作用详解
2021/04/27 MySQL
Spring Boot mybatis-config 和 log4j 输出sql 日志的方式
2021/07/26 Java/Android
css中:last-child不生效的解决方法
2022/08/05 HTML / CSS