Django用openLDAP做认证
前言
之前有需求要做一个django+ldap用户管理的简单接口,研究了好几个模块,最后终于能实现django用ldap做用户认证了。也是自己的水平有限吧,做了好长时间,现在就和大家分享一下这个过程吧。最终是有两种方法实现这个认证过程,一种是通过django-python3-ldap实现的,一种是自己写了一个简单的。我下面有个示例程序在github上面,这个程序是两个方法都能用,而且我放到了一个django的app下。大家可以下载下来看看。
基本信息
具体如下:
python pip信息:
bogon:ldapdemo hongzhi.wang$ pip list|egrep -i 'django|ldap'
Django                                 1.8.11
django-auth-ldap                       1.2.9
django-bootstrap-form                  3.2.1
django-celery                          3.1.16
django-crontab                         0.7.1
django-python3-ldap                    0.9.11
djangorestframework                    3.6.2
ldap3                                  1.4.0
python-ldap                            2.4.32
ldap 相关信息(在我自己的虚拟机上面搭的):
192.168.3.3:389
dn: cn=user03,ou=People,dc=node1,dc=com secret:555
dn: cn=user02,ou=People,dc=node1,dc=com secret:555
dn: cn=user01,ou=People,dc=node1,dc=com secret:555
user02的详细信息
dn: cn=user02,ou=People,dc=node1,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
homeDirectory: /home/user02
loginShell: /bin/bash
uid: user02
cn: user02
uidNumber: 10002
gidNumber: 100
sn: user02
mail: user02@qq.com
userPassword:: e1NTSEF9WEZXOWMxaFZFMjVaK3JnV3Q3a1FDWW0wdWxjRVZrVk8=
示例程序地址在此:https://github.com/WisWang/ldapdemo
目录结构如下:
bogon:PycharmProjects hongzhi.wang$ tree ldapdemo/|grep -v pyc
ldapdemo/
├── db.sqlite3
├── ldapdemo
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py
├── my_ldap_auth
│   ├── __init__.py
│   ├── admin.py
│   ├── django_python3_ldap_settings.py
│   ├── ldap_tool.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── models.py
│   ├── mysettings.py
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
├── static
│   ├── css
│   │   ├── bootstrap.css
│   │   ├── bootstrap.min.css
│   │   └── custom.css
│   └── js
│       ├── bootstrap.js
│       ├── bootstrap.min.js
│       └── jquery-2.2.2.js
└── templates
    ├── home.html
    ├── ldap_auth.html
    └── login_content.html
本次还用了django-python3-ldap
我自己实现的python+django认证
基本思路就是通过python-ldap这个模块自己封装了一个类,然后实现各种用到的方法,
认证过程就是拿到用户名密码后,先通过这个ldapdemo/my_ldap_auth/ldap_tool.py里的如下方法验证用户名存不存在,存在返回这个用户的dn(这种方法缺点是用户名在这个basedn下面必须唯一,不过可以通过让用户输入部门名输入到后台,然后再search的时候添加ou筛选就能实现用户在不同部门但是用户名相同的认证,本文就再多做叙述了。)
def check_user(self, username):
    self.conn.simple_bind_s(USER, PASSWORD)
    filter = '(uid=%s)' % username
    attrs = ['sn', 'uid']
    ret = self.conn.search_s(BASE_DN, ldap.SCOPE_SUBTREE, filter, attrs)
    if ret:
        return ret[0][0]
    else:
        return False
拿到用户名后self.conn.simple_bind_s(dn,userpass)这样去server端检查用户名,密码。
然后就是这段代码了ldapdemo/my_ldap_auth/views.py:
ldaptool = LdapTool()
res = ldaptool.check_pass(username,password)
#res这个放回值是我自定义的,详见代码吧
if res == 0:
    user = User.objects.filter(username=username)
    if not user:
        u = User.objects.create_user(username=username, password="asdf1234")
    else:
        u = user[0]
        u.set_password("asdf1234")
    u.save()
    user = authenticate(username=username, password='asdf1234')
    login(request, user)
    return HttpResponseRedirect('/')
elif res == 1:
    err_msg = "username not found"
else:
    err_msg = "password wrong"
return render(request, 'ldap_auth.html', {'err_msg': err_msg, })
基本思路就是ldap验证通过以后,检查django默认的User表有没有这个用户,没有就创建,然后把这个用户登录。(这个是每次有用户认证都会和ldapserver建立一个连接,之前是在django启动的时候我就建立一个连接,各有优缺点吧。)
通过django-python3-ldap实现的认证
这个基本就是按照这个django-python3-ldap在github上面那个readme来做的,但是遇到些问题,我把原来的代码改了一处,就能用了,但是感觉限制有些多,下面就来说一下吧。
在配置文件中有如下配置
# The LDAP username and password of a user for authenticating the `ldap_sync_users`
# management command. Set to None if you allow anonymous queries.
LDAP_AUTH_CONNECTION_USERNAME = "admin"
LDAP_AUTH_CONNECTION_PASSWORD = "secret"
它./manage.py ldap_sync_users这样同步用户的时候,由于这个配置一下配置:
# The LDAP search base for looking up users.
LDAP_AUTH_SEARCH_BASE = "ou=people,dc=example,dc=com"
# User model fields mapped to the LDAP
# attributes that represent them.
LDAP_AUTH_USER_FIELDS = {
    "username": "uid",
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
}
这个admin用户
的dn就会变成"uid=admin,ou=people,dc=example,dc=com"不是我们希望的"uid=admin,dc=example,dc=com"因为一般admin是有没有ou这个属性的(我的理解是这样),这个同步成功不了。
我把site-packages/django_python3_ldap/ldap.py这个文件其中第120行左右的内容改成如下:
if kwargs:
    password = kwargs.pop("password")
    if username != "cn=admin,dc=node1,dc=com":
        username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME)(kwargs)
# Make the connection.
print "***",username # 这样就可以看到他这个模块加工后的dn了,打印出来方便自己检查问题,如果认证不了加上这个基本很多问题都能解决,我还停留在print debug阶段呢,以后要设置断点来debug了O(∩_∩)O~
这样就可以通过这个admin来同步用户信息了。
结语
本文我自己实现的认证是通过python-ldap实现的,不过ldap3是更pythonic的模块,我研究了一下,其实完全可以替代python-ldap这个模块的,不过我这个都写完了,ldap3的使用就放在以后吧,我再研究的过程中还在stackoverflow上面问过通过python ldap的模块在不知道用户密码的情况下通过admin给用户重置密码的方法呢,问题链接,最后还是我自己仔细看了官方文档,给解决了,这里面有python-ldap和ldap3的官方文档连接,大家可以看看。我的blog开始有我自己的联系方式啥的,有问题随时问哈。
Django用openLDAP做认证的更多相关文章
- 基于django rest framework做认证组件
		
先导入要用到的类 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions ...
 - Django集成OpenLDAP认证
		
本文详细介绍了django-auth-ldap的使用方法,参数含义,并提供了示例代码 版本说明 Django==2.2 django-auth-ldap==1.7.0 集成过程 Django集成LDA ...
 - [原创]django+ldap实现统一认证部分二(python-ldap实践)
		
前言 接上篇文章 [原创]django+ldap实现统一认证部分一(django-auth-ldap实践) 继续实现我们的统一认证 python-ldap 我在sso项目的backend/lib/co ...
 - [原创]django+ldap实现统一认证部分一(django-auth-ldap实践)
		
前言 接之前我的文章,django+ldap+memcache实现单点登录+统一认证 ,ldap部署相关,ldap双机\LAM配置管理\ldap备份还原,目前来说,我们已经有了高可用性的ldap环境了 ...
 - Django 中的用户认证
		
Django 自带一个用户认证系统,这个系统处理用户帐户.组.权限和基于 cookie 的 会话.本文说明这个系统是如何工作的. 概览 认证系统由以下部分组成: 用户 权限:控制用户进否可以执行某项任 ...
 - django内置的认证系统
		
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
 - Django+JWT实现Token认证
		
对外提供API不用django rest framework(DRF)就是旁门左道吗? 基于Token的鉴权机制越来越多的用在了项目中,尤其是对于纯后端只对外提供API没有web页面的项目,例如我们通 ...
 - Django Rest Framework之认证
		
代码基本结构 url.py: from django.conf.urls import url, include from web.views.s1_api import TestView urlpa ...
 - Django Rest framework 之  认证
		
django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...
 
随机推荐
- JAVA中循环删除list中元素的方法总结(同上篇)
			
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...
 - linux 查看任务运行时间
			
ps -eo pid,tty,user,comm,lstart,etime | grep pid 15590 ? meicai java Wed Sep 26 20:04:31 2018 35-15: ...
 - linux安装jdk8
			
1.文件准备 jdk-8u201-linux-x64.tar.gz 下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8- ...
 - <记录> PHP监控进程状态,完成掉线自动重启
			
1. 利用Shell脚本实现 #!/bin/bash PORT= while [ true ];do read -p "please enter the port that you want ...
 - json&pickle&shelve模块
			
之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了 ...
 - Unity3D AssetBundle相关
			
Unity3D AssetBundle相关 首先,先看一下原理吧 Unity3D研究院之Assetbundle的原理(六十一) 其次,接着往下看:Unity3D研究院之Assetbundle的实战( ...
 - Django 重写用户模型
			
AUTH_USER_MODEL = 'myapp.MyUser' django——重写用户模型 Django内建的User模型可能不适合某些类型的项目.例如,在某些网站上使用邮件地址而不是用户名作为身 ...
 - Curl 基本命令
			
下载单个文件,默认将输出打印到标准输出中(STDOUT)中 curl http://www.centos.org 通过-o/-O选项保存下载的文件到指定的文件中:-o:将文件保存为命令行中指定的文件名 ...
 - 151. Reverse Words in a String翻转一句话中的单词
			
[抄题]: Given an input string, reverse the string word by word. Example: Input: "the sky is blue& ...
 - spring多线程
			
Spring4.x高级话题(二):多线程 一. 点睛 Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程.使用ThreadPoolTaskExecutor可实现一个基于线程池 ...