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 相关文章推荐
win7安装python生成随机数代码分享
Dec 27 Python
python3访问sina首页中文的处理方法
Feb 24 Python
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
Jul 04 Python
基于anaconda下强大的conda命令介绍
Jun 11 Python
python numpy 部分排序 寻找最大的前几个数的方法
Jun 27 Python
Python 给某个文件名添加时间戳的方法
Oct 16 Python
Django网络框架之创建虚拟开发环境操作示例
Jun 06 Python
python二进制文件的转译详解
Jul 03 Python
Python Celery多队列配置代码实例
Nov 22 Python
pytorch ImageFolder的覆写实例
Feb 20 Python
使用 pytorch 创建神经网络拟合sin函数的实现
Feb 24 Python
Keras官方中文文档:性能评估Metrices详解
Jun 15 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
destoon找回管理员密码的方法
2014/06/21 PHP
PHP利用MySQL保存session的实现思路及示例代码
2014/09/09 PHP
PHP获取路径和目录的方法总结【必看篇】
2017/03/04 PHP
php实现支付宝当面付(扫码支付)功能
2018/05/30 PHP
laravel框架模型和数据库基础操作实例详解
2020/01/25 PHP
JavaScript在IE和Firefox浏览器下的7个差异兼容写法小结
2010/06/18 Javascript
用jquery实现动画跳到顶部和底部(这个比较简单)
2014/09/01 Javascript
提高jQuery性能优化的技巧
2015/08/03 Javascript
使用postMesssage()实现跨域iframe页面间的信息传递方法
2016/03/29 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
2016/04/06 Javascript
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
vue element-ui table表格滚动加载方法
2018/03/02 Javascript
React Form组件的实现封装杂谈
2018/05/07 Javascript
使用apifm-wxapi快速开发小程序过程详解
2019/08/05 Javascript
layer.prompt输入层的例子
2019/09/24 Javascript
es6中使用map简化复杂条件判断操作实例详解
2020/02/19 Javascript
Vue中inheritAttrs的使用实例详解
2020/12/31 Vue.js
零基础写python爬虫之urllib2使用指南
2014/11/05 Python
Python入门教程之if语句的用法
2015/05/14 Python
python实现简单点对点(p2p)聊天
2017/09/13 Python
TensorFlow在MAC环境下的安装及环境搭建
2017/11/14 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
Python任意字符串转16, 32, 64进制的方法
2019/06/12 Python
python生成并处理uuid的实现方式
2020/03/03 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
Scrapy实现模拟登录的示例代码
2021/02/21 Python
Crucial英睿达法国官网:内存条及SSD固态硬盘升级
2018/07/13 全球购物
高职助产应届生自荐信
2013/09/24 职场文书
考博自荐信
2013/10/25 职场文书
教师找工作推荐信
2013/11/23 职场文书
井冈山红色之旅心得体会
2014/10/07 职场文书
岗位竞聘报告范文
2014/11/06 职场文书
2015年志愿者服务工作总结
2015/04/20 职场文书
催款函范本大全
2015/06/24 职场文书
财务年终工作总结大全
2019/06/20 职场文书
零基础学java之方法的定义与调用详解
2022/04/10 Java/Android