[原创]django+ldap实现统一认证部分一(django-auth-ldap实践)
前言
接之前我的文章,django+ldap+memcache实现单点登录+统一认证 ,ldap部署相关,ldap双机\LAM配置管理\ldap备份还原,目前来说,我们已经有了高可用性的ldap环境了,里边也有了一些用户信息,后边要说一说通过django调用ldap的实现方式,里边主要涉及3个模块,django-auth-ldap:用于从ldap同步账户、登录验证,它和ldap结合的很好,但它不能反向直接操作ldap,只能进行从ldap向下游系统的同步,所以还需要python-ldap模块,以便实现反向对ldap的增删改查,我这边的具体需求就是注册用户、重置密码等,另外还需要一个python-memcached,用于把生成的session放到mc中
查了网上大量的关于django+ldap实现统一认证的文章,大部分都是只写了django-auth-ldap或者python-ldap来实现,但是如果要实现一套完整的统一认证系统,实际上这2个模块都是需要的
django-auth-ldap
这个模块,基本在settings.py通过配置就可以拿来用了,基本不需要对代码做什么修改。用于从ldap里拿到信息传给sso系统做后续处理,但通过它无法让sso系统反向操作ldap,无论django的前台和admin都适用
官方文档: https://pythonhosted.org/django-auth-ldap/authentication.html
中文翻译: https://darkcooking.gitbooks.io/django-auth-ldap/content/chapter9.html
不过这个翻译版是个简化版本,有的东西不全,不过基本也够用了,并且网站打开很慢,我把它的pdf放在这里,可以自行查看 http://files.cnblogs.com/files/caseast/django-auth-ldap.pdf
django官网(session部分):https://docs.djangoproject.com/en/1.10/topics/http/sessions/
ok!直接上代码吧,具体的配置说明,不明确的还请参考官方文档,里边我把log模块和session这部分配置也写一下顺道,不单独开篇描述了
---settings.py---
SESSION_ENGINE = "django.contrib.sessions.backends.cache" # 另外还有个cached_db,这两个的区别是,cache只写缓存,cached_db除了写缓存还同时写数据库,如果对于session的安全性要求高可以选择cached_db
SESSION_COOKIE_AGE = 86400 # 设置session有效期为一天,默认两周
SESSION_COOKIE_DOMAIN = ".ssotest.net" # 此配置不能解决跨域问题,但是能解决a.ssotest.net与b.ssotest.net的session共享问题,不加此属性,跨站(非跨域)时,无法传递session
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [ # 连接的是2个mc,python-memcached本身有监活,挂一个mc会自动将请求分配到好的mc上
'ldap1.prod.bj1.ssotest.net:11211',
'ldap2.prod.bj1.ssotest.net:11211',
],
'TIMEOUT': 30,
'OPTIONS': {
'MAX_ENTRIES': 3000
}
}
}
LOGIN_URL = "/account/login/"
# ### ldap 配置部分BEGIN ### #
import ldap
from django_auth_ldap.config import LDAPSearch, PosixGroupType
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend', # 配置为先使用LDAP认证,如通过认证则不再使用后面的认证方式
'django.contrib.auth.backends.ModelBackend', # sso系统中手动创建的用户也可使用,优先级靠后。注意这2行的顺序
)
base_dn = 'dc=ldap,dc=ssotest,dc=net'
AUTH_LDAP_SERVER_URI = 'ldap://ldap.ssotest.net'
AUTH_LDAP_BIND_DN = 'uid=ssoadmin,ou=People,dc=ldap,dc=ssotest,dc=net'
AUTH_LDAP_BIND_PASSWORD = 'ssotest@123'
AUTH_LDAP_USER_SEARCH = LDAPSearch('ou=People,%s' % base_dn, ldap.SCOPE_SUBTREE, "(uid=%(user)s)") # 用户的DN是uid=caojun,ou=People,dc=ldap,dc=ssotest,dc=net,所以用uid
AUTH_LDAP_ALWAYS_UPDATE_USER = True # This is the default, but I like to be explicit.
AUTH_LDAP_USER_ATTR_MAP = { # key为数据库字段名,value为ldap中字段名,此字典解决django model与ldap字段名可能出现的不一致问题
"username": "uid",
"name": "cn",
"email": "mail"
}
# 组权限管理 #
AUTH_LDAP_GROUP_SEARCH = LDAPSearch('ou=Group,dc=ldap,dc=ssotest,dc=net', ldap.SCOPE_SUBTREE, "(objectClass=posixGroup)")
AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr="cn") # 组的DN是cn=员工,ou=Group,dc=ldap,dc=ssotest,dc=net,所以type是cn
AUTH_LDAP_USER_FLAGS_BY_GROUP = { # django admin的is_staff|superuser属性映射为ldap的管理员
"is_staff": u"cn=管理员,ou=Group,dc=ldap,dc=ssotest,dc=net",
"is_superuser": u"cn=管理员,ou=Group,dc=ldap,dc=ssotest,dc=net"
}
AUTH_LDAP_REQUIRE_GROUP = u"cn=员工,ou=Group,dc=ldap,dc=ssotest,dc=net" # 只有此group可用ldap进行认证
AUTH_LDAP_DENY_GROUP = u"cn=黑名单,ou=Group,dc=ldap,dc=ssotest,dc=net" # 此group不能使用ldap进行认证,直接deny掉,不会后续往django创建信息
AUTH_LDAP_MIRROR_GROUPS = True # 直接把ldap的组复制到django一份,和AUTH_LDAP_FIND_GROUP_PERMS互斥.用户每次登录会根据ldap来更新数据库的组关系
# AUTH_LDAP_FIND_GROUP_PERMS = True # django从ldap的组权限中获取权限,这种方式,django自身不创建组,每次请求都调用ldap
# AUTH_LDAP_CACHE_GROUPS = True # 如打开FIND_GROUP_PERMS后,此配置生效,对组关系进行缓存,不用每次请求都调用ldap
# AUTH_LDAP_GROUP_CACHE_TIMEOUT = 600 # 缓存时间
# ### ldap 配置部分END ### #
# ### log 配置部分BEGIN ### #
LDAP_LOGS = os.path.join(BASE_DIR, 'logs/ldap.log')
stamdard_format = '[%(asctime)s][%(threadName)s:%(thread)d]' + \
'[task_id:%(name)s][%(filename)s:%(lineno)d] ' + \
'[%(levelname)s]- %(message)s'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': { # 详细
'format': stamdard_format
},
},
'handlers': {
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': LDAP_LOGS,
'maxBytes': 1024 * 1024 * 100, # 5 MB
'backupCount': 5,
'formatter': 'standard',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
}
},
'loggers': {
'': { # default日志,存放于log中
'handlers': ['default'],
'level': 'DEBUG',
},
'django_auth_ldap': { # django_auth_ldap模块相关日志打印到console
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False, # 选择关闭继承,不然这个logger继承自默认,日志就会被记录2次了(''一次,自己一次)
},
# 'django.db.backends': { # 数据库相关执行过程log打印到console
# 'handlers': ['console'],
# 'level': 'DEBUG',
# },
}
}
# ### log 配置部分END ### #
logging模块的说明,可以参考这篇文章 http://www.jianshu.com/p/d615bf01e37b ,这个配置可以配置到settings.py中,这样django项目都会自动调用,或者单独写入一个log_config文件中,需要时手动调用,例子如下
log_config.py
import logging
from logging.config import dictConfig
logging_config={
........
}
dictConfig(logging_config) #注册一下配置
调用方法:
import logging
logger = logging.getLogger()
logger.error('ldap conn失败,原因为: %s' % str(e))
额外说一点,以上配置是在sso系统进行,如果下游系统接入到sso系统的话,顺序就是ldap--> sso --> 项目A,默认接入后,项目A的前台账户就可以使用ldap进行管理,但项目A如果使用了django admin的话(因为前台的登录动作会强制转到sso上,而admin如果不改源码做不到这点),django admin是会走本地的账户的,这样就会出现,一个下游系统的管理员用户,前台一个密码,后台一个密码,所以我们需要给下游系统的settings.py做一定配置,让下游的admin账户也从ldap中同步,下游同样需要开篇说的3个python模块
项目A的settings.py
# ### ldap 配置部分BEGIN (If use Django-admin,configure it!) ### #
'''just for admin,前台认证统一走认证平台,所以下游系统不保存密码,导致下游无法登录admin(如使用),所以admin添加ldap认证,只用ldap只读账户即可'''
import ldap
from django_auth_ldap.config import LDAPSearch, PosixGroupType
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend', # 配置为先使用LDAP认证,如通过认证则不再使用后面的认证方式
'django.contrib.auth.backends.ModelBackend', # 同时打开本地认证,因为下游系统的权限和组关系需要用到
)
base_dn = 'dc=ldap,dc=ssotest,dc=net'
AUTH_LDAP_SERVER_URI = 'ldap://ldap.ssotest.net'
AUTH_LDAP_BIND_DN = 'uid=ssoread,ou=People,dc=ldap,dc=ssotest,dc=net' # read only ldap user
AUTH_LDAP_BIND_PASSWORD = 'ssotest@123'
AUTH_LDAP_USER_SEARCH = LDAPSearch('ou=People,%s' % base_dn, ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
AUTH_LDAP_ALWAYS_UPDATE_USER = False # Default is True,是否登录后从ldap同步用户,不进行同步,因为下游的用户表是什么样的不能确定,只能确定它也使用邮箱前缀
# 下游系统不从ldap同步group staff/superuser相关,但需要从ldap验证用户是否离职
AUTH_LDAP_GROUP_SEARCH = LDAPSearch('ou=Group,dc=ldap,dc=ssotest,dc=net', ldap.SCOPE_SUBTREE, "(objectClass=posixGroup)")
AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr="cn")
AUTH_LDAP_REQUIRE_GROUP = u"cn=员工,ou=Group,dc=ldap,dc=ssotest,dc=net"
AUTH_LDAP_DENY_GROUP = u"cn=黑名单,ou=Group,dc=ldap,dc=ssotest,dc=net"
AUTH_LDAP_FIND_GROUP_PERMS = True # django从ldap的组权限中获取权限,这种方式,django自身不创建组,每次请求都调用ldap,下游子系统,我们并不需要让他同步ldap里的"员工","管理员"这种表,所以不用mirror_groups
AUTH_LDAP_CACHE_GROUPS = True # 如打开FIND_GROUP_PERMS后,才生效,对组关系进行缓存,不用每次请求都调用ldap
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 600
# ### ldap 配置部分END ### #
以上,我们通过配置,就可以完成django对于ldap的调用了,我们可以通过ldap来管理我们的前台和admin中的账户和密码,但是这个动作是向下进行的,如果想通过我们的单点登录系统来操作ldap,这个django-auth-ldap是没有这个功能的。这就需要后边的python-ldap了.
篇幅限制,python-ldap请参考我的这篇文章[原创]django+ldap实现统一认证部分二(python-ldap实践)
参考资料
https://pythonhosted.org/django-auth-ldap/authentication.html
https://darkcooking.gitbooks.io/django-auth-ldap/content/chapter9.html
https://docs.djangoproject.com/en/1.10/topics/http/sessions/
http://www.jianshu.com/p/d615bf01e37b
[原创]django+ldap实现统一认证部分一(django-auth-ldap实践)的更多相关文章
- [原创]django+ldap实现统一认证部分二(python-ldap实践)
前言 接上篇文章 [原创]django+ldap实现统一认证部分一(django-auth-ldap实践) 继续实现我们的统一认证 python-ldap 我在sso项目的backend/lib/co ...
- LDAP+Gitea统一认证Git服务器账户管理openLdap和微软的ad
很多时候我们需要管理多个内容管理系统,比如Jira.Jenkins.GitEA/Gitlab等等各种管理系统,我们需要每一套管理系统每个人都管理一套密码,每套系统每套密码简直是一种灾难,于是LDAP可 ...
- [原创]django+ldap+memcache实现单点登录+统一认证
前言 由于公司内部的系统越来越多,为了方便用户使用,通过django进行了单点登录和统一认证的尝试,目前实现了django项目的单点登录和非django项目的统一认证,中间波折挺多,涉及的技术包括dj ...
- openvpn通过ldap或ad统一认证解决方案思路分享
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/986933 缘起:成 ...
- LDAP实现企业异构平台的统一认证
LDAP实现企业异构平台的统一认证 技术是为应用服务的,没有应用,技术就无用武之地.同样光配置完LDAP服务器没有任何意义,只有把所有需要认证的环节,只有纳入LDAP系统中,才能使它发挥应有 ...
- Linux下LDAP统一认证解决方案
Linux下LDAP统一认证解决方案 --http://www.cangfengzhe.com/wangluoanquan/3.html 转自:http://www.cnblogs.com/MYSQL ...
- #研发解决方案介绍#IdCenter(内部统一认证系统)
郑昀 基于朱传志的设计文档 最后更新于2014/11/13 关键词:LDAP.认证.权限分配.IdCenter. 本文档适用人员:研发 曾经一个IT内部系统配一套帐号体系和授权 线上生产环境里 ...
- Django 中的用户认证
Django 自带一个用户认证系统,这个系统处理用户帐户.组.权限和基于 cookie 的 会话.本文说明这个系统是如何工作的. 概览 认证系统由以下部分组成: 用户 权限:控制用户进否可以执行某项任 ...
- Django用openLDAP做认证
前言 之前有需求要做一个django+ldap用户管理的简单接口,研究了好几个模块,最后终于能实现django用ldap做用户认证了.也是自己的水平有限吧,做了好长时间,现在就和大家分享一下这个过程吧 ...
随机推荐
- js中参数不对应问题
因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java和C#一样对其传入参数的类型进行定义.那么传入参数的个数有没有影响呢?今天小猪就做了个实 ...
- HTML5 localStorage本地存储
介绍 localStorage(本地存储)的使用方式.包括对存储对象的添加.修改.删除.事件触发等操作. 目录 1. 介绍 1.1 说明 1.2 特点 1.3 浏览器最小版本支持 1.4 适合场景 2 ...
- Javacript实现字典结构
字典是一种用[键,值]形式存储元素的数据结构.也称作映射,ECMAScript6中,原生用Map实现了字典结构. 下面代码是尝试用JS的Object对象来模拟实现一个字典结构. <script& ...
- iOS app内存分析套路
iOS app内存分析套路 Xcode下查看app内存使用情况有2中方法: Navigator导航栏中的Debug navigator中的Memory Instruments 一.Debug navi ...
- 如何给FineReport设置自定义消息提醒工具
FineReport设计器有自动的消息推送功能,可设置报表定时推送和常规的日报周报推送.官方有自己的消息推送的接口,不过有些用户旺旺希望自己开发,符合自己需求的推送界面. 下面这个方案就从逻辑层面简单 ...
- 探索c#之Async、Await剖析
阅读目录: 基本介绍 基本原理剖析 内部实现剖析 重点注意的地方 总结 基本介绍 Async.Await是net4.x新增的异步编程方式,其目的是为了简化异步程序编写,和之前APM方式简单对比如下. ...
- Egret3D 研究报告(一)初试
了解的朋友应该知道我最近一直都在鼓吹webgl. 今天有一点时间,加了一个Egret3D的群,就开始了这个坑. 耳听为虚,眼见为实.让我们荡起双桨,一起去刷一下egret 打开姿势 至于以什么姿势打开 ...
- CS Coder学习asp.net5个月的最大感悟:从http的角度重新认识asp.net(二)——我理解的ajax(二)
啊哈,时隔两个月,才开始写上一篇文章的后续,实在是惭愧.主要是年尾公司又来活了,忙得团团转,而且这段时间在自学mvc.我在上文中,提到过我对mvc框架的初步印象是:相比webform,算是回归了bs本 ...
- .NET里简易实现IoC
.NET里简易实现IoC 前言 在前面的篇幅中对依赖倒置原则和IoC框架的使用只是做了个简单的介绍,并没有很详细的去演示,可能有的朋友还是区分不了依赖倒置.依赖注入.控制反转这几个名词,或许知道的也只 ...
- ASP.NET Identity入门系列教程(一) 初识Identity
摘要 通过本文你将了解ASP.NET身份验证机制,表单认证的基本流程,ASP.NET Membership的一些弊端以及ASP.NET Identity的主要优势. 目录 身份验证(Authentic ...