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 03 Python
Python环境变量设置方法
Aug 28 Python
Python排序搜索基本算法之希尔排序实例分析
Dec 09 Python
python之从文件读取数据到list的实例讲解
Apr 19 Python
django允许外部访问的实例讲解
May 14 Python
Pandas 同元素多列去重的实例
Jul 03 Python
Python lxml解析HTML并用xpath获取元素的方法
Jan 02 Python
详解如何设置Python环境变量?
May 13 Python
解决Python3下map函数的显示问题
Dec 04 Python
python pandas利用fillna方法实现部分自动填充功能
Mar 16 Python
Python读入mnist二进制图像文件并显示实例
Apr 24 Python
python 基于UDP协议套接字通信的实现
Jan 22 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使用环形链表解决约瑟夫问题完整示例
2018/08/07 PHP
PHP类与对象后期静态绑定操作实例详解
2018/12/20 PHP
php/JS实现的生成随机密码(验证码)功能示例
2019/06/06 PHP
可以用来调试JavaScript错误的解决方案
2010/08/07 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
JS获取select-option-text_value的方法
2013/12/26 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
JavaScript事件委托实例分析
2015/05/26 Javascript
javascript引用类型之时间Date和数组Array
2015/08/27 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
2016/03/01 Javascript
Node.js中路径处理模块path详解
2016/11/14 Javascript
原生js实现瀑布流布局
2017/03/08 Javascript
微信小程序滚动Tab实现左右可滑动切换
2017/08/17 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
Puppet的一些技巧
2018/09/17 Javascript
vue ssr 实现方式(学习笔记)
2019/01/18 Javascript
小程序自定义单页面、全局导航栏的实现代码
2019/03/15 Javascript
详解使用React.memo()来优化函数组件的性能
2019/03/19 Javascript
js利用递归与promise 按顺序请求数据的方法
2019/08/30 Javascript
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
wepy--用vantUI 实现上弹列表并选择相应的值操作
2020/11/03 Javascript
python读取oracle函数返回值
2016/07/18 Python
Python基础教程之利用期物处理并发
2018/03/29 Python
利用Python半自动化生成Nessus报告的方法
2019/03/19 Python
利用python生成照片墙的示例代码
2020/04/09 Python
canvas探照灯效果的示例代码
2018/11/30 HTML / CSS
Madewell澳大利亚官方网站:美国休闲服饰品牌
2019/07/18 全球购物
自荐信范文
2013/12/10 职场文书
有关爱国演讲稿
2014/05/07 职场文书
环保倡议书100字
2014/05/15 职场文书
总经理任命书范本
2014/06/05 职场文书
一年级数学上册复习计划
2015/01/17 职场文书
2015年采购员工作总结
2015/04/27 职场文书
幸福来敲门观后感
2015/06/04 职场文书
《巨人的花园》教学反思
2016/02/19 职场文书
vue3.0 数字翻牌组件的使用方法详解
2022/04/20 Vue.js