前言

接之前我的文章,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实践)的更多相关文章

  1. [原创]django+ldap实现统一认证部分二(python-ldap实践)

    前言 接上篇文章 [原创]django+ldap实现统一认证部分一(django-auth-ldap实践) 继续实现我们的统一认证 python-ldap 我在sso项目的backend/lib/co ...

  2. LDAP+Gitea统一认证Git服务器账户管理openLdap和微软的ad

    很多时候我们需要管理多个内容管理系统,比如Jira.Jenkins.GitEA/Gitlab等等各种管理系统,我们需要每一套管理系统每个人都管理一套密码,每套系统每套密码简直是一种灾难,于是LDAP可 ...

  3. [原创]django+ldap+memcache实现单点登录+统一认证

    前言 由于公司内部的系统越来越多,为了方便用户使用,通过django进行了单点登录和统一认证的尝试,目前实现了django项目的单点登录和非django项目的统一认证,中间波折挺多,涉及的技术包括dj ...

  4. openvpn通过ldap或ad统一认证解决方案思路分享

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/986933 缘起:成 ...

  5. LDAP实现企业异构平台的统一认证

    LDAP实现企业异构平台的统一认证      技术是为应用服务的,没有应用,技术就无用武之地.同样光配置完LDAP服务器没有任何意义,只有把所有需要认证的环节,只有纳入LDAP系统中,才能使它发挥应有 ...

  6. Linux下LDAP统一认证解决方案

    Linux下LDAP统一认证解决方案 --http://www.cangfengzhe.com/wangluoanquan/3.html 转自:http://www.cnblogs.com/MYSQL ...

  7. #研发解决方案介绍#IdCenter(内部统一认证系统)

    郑昀 基于朱传志的设计文档 最后更新于2014/11/13 关键词:LDAP.认证.权限分配.IdCenter. 本文档适用人员:研发   曾经一个IT内部系统配一套帐号体系和授权   线上生产环境里 ...

  8. Django 中的用户认证

    Django 自带一个用户认证系统,这个系统处理用户帐户.组.权限和基于 cookie 的 会话.本文说明这个系统是如何工作的. 概览 认证系统由以下部分组成: 用户 权限:控制用户进否可以执行某项任 ...

  9. Django用openLDAP做认证

    前言 之前有需求要做一个django+ldap用户管理的简单接口,研究了好几个模块,最后终于能实现django用ldap做用户认证了.也是自己的水平有限吧,做了好长时间,现在就和大家分享一下这个过程吧 ...

随机推荐

  1. 【SQLServer】【恢复挂起的解决方案】附加文件时候的提示“无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。 ”【数据库恢复】

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 先贴错误: 吐槽一下: 进入正题: 新建一个同名数据库 停止MSSQL服务 替换数据库文 ...

  2. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  3. 使用Oracle官方巡检工具ORAchk巡检数据库

    ORAchk概述 ORAchk是Oracle官方出品的Oracle产品健康检查工具,可以从MOS(My Oracle Support)网站上下载,免费使用.这个工具可以检查Oracle数据库,Gold ...

  4. 【Reading Note】Python读书杂记

    赋值 >>> list=[] >>> app=[list,list,list] >>> app [[], [], []] >>> ...

  5. ADO.NET一小记-select top 参数问题

    异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html 最近使用ADO.NET的时候,发现select top @count xxxx 不 ...

  6. JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  7. 在MySQL数据库中创建一个完整的表

    1.登陆成功后,首先进入某一个数据库 (不是指数据库服务器) use t1; //t1是数据库名 如图所示: 2.在此数据库中建立数据库表 2.1 先建立表结构(可以理解为表的列名,也就是字段名)在实 ...

  8. Josephus环类问题,java实现

    写出一个双向的循环链表,弄一个计数器,我定义的是到三的时候,自动删除当前节点,很简单. package Com; import java.util.Scanner; /* * 约瑟夫环问题,有n个人组 ...

  9. [转]thinkphp 模板显示display和assign的用法

    thinkphp 模板显示display和assign的用法 $this->assign('name',$value); //在 Action 类里面使用 assign 方法对模板变量赋值,无论 ...

  10. Yeoman 学习笔记

    yoeman 简介:http://www.infoq.com/cn/news/2012/09/yeoman yeoman 官网: http://yeoman.io/ yeoman 是快速创建骨架应用程 ...