基于LDAP实现统一认证服务
# 基于LDAP实现统一认证服务
# 简介
应用 系统在用户管理上 存在 的问题 ,提 出统一 用户认 证解 决方案。利用 LDAP 目录服务,构建一套统一的身份认证机制及网络应用资源管理模式,实现对用户的统一身份认证、单点登录、集中鉴权以及对 网络应用资源的统一管理 。
关键词 目录服务 ,统一身份认证 ,单点登 录,集 中鉴权
# 链接资料
基于LDAP的统一用户认证系统设计与实现 设计文档
https://www.jsjkx.com/CN/article/openArticlePDF.jsp?id=8940
ldap go语言实现数据库结构 客户端
https://github.com/eryajf/go-ldap-admin/tree/main/model
python-ldap第三方安装包
python-ldap - python-ldap 3.4.2 documentation (opens new window)
openldap搭建和配置
csdn java
<https://blog.csdn.net/u013310119/article/details/109402932>
乾颐堂-python操作ldap微软域 <https://gitee.com/qytang/VIP_LDAP3>
django对接 官网ldap
<https://django-auth-ldap.readthedocs.io/en/latest/install.html>
对接企业微信
<https://blog.csdn.net/weixin_43881394/article/details/109116711>
搭建openldap
<https://www.cnblogs.com/lcword/p/14434499.html>
2
3
4
5
6
7
8
9
10
11
12
# 1. LDAP概念和原理介绍
相信对于许多的朋友来说,可能听说过LDAP,但是实际中对LDAP的了解和具体的原理可能还比较模糊,今天就从“什么是LDAP”、“LDAP的主要产品”、“LDAP的基本模型”、“LDAP的使用案例”四个方面来做一个介绍。
我们在开始介绍之前先来看几个问题:
- 我们日常的办公系统是不是有多个?
- 每个系统之间是不是都有独立的账号密码?
- 密码多了,有时候半天想不起来哪个密码对应哪个系统?
- 每次新项目的开发,都需要重新开发和维护一套用户密码?
- 维护多套系统的用户是不是非常头疼?
So,如今大家再也不用为上面的的问题头疼了,因为“LDAP统一认证服务”已经帮助大家解决这些问题了。那么相信大家对“LDAP统一认证服务”是干嘛的已经有一个大概的了解了吧?
# 1.1 什么是LDAP?
(一)在介绍什么是LDAP之前,我们先来复习一个东西:“什么是目录服务?”
- 目录服务是一个特殊的数据库,用来保存描述性的、基于属性的详细信息,支持过滤功能。
- 是动态的,灵活的,易扩展的。
如:人员组织管理,电话簿,地址簿。
(二)了解完目录服务后,我们再来看看LDAP的介绍:
LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。按照我们对文件目录的理解,ldap可以看成一个文件系统,类似目录和文件树。
目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。
LDAP目录服务是由目录数据库和一套访问协议组成的系统。
目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。
(三)为什么要使用
LDAP是开放的Internet标准,支持跨平台的Internet协议,在业界中得到广泛认可的,并且市场上或者开源社区上的大多产品都加入了对LDAP的支持,因此对于这类系统,不需单独定制,只需要通过LDAP做简单的配置就可以与服务器做认证交互。“简单粗暴”,可以大大降低重复开发和对接的成本。
我们拿开源系统(YAPI)做案例,只需做一下简单的几步配置就可以达到LDAP的单点登录认证了:
{
"ldapLogin": {
"enable": true,
"server": "ldap://l-ldapt1.ops.dev.cn0.qunar.com",
"baseDn": "CN=Admin,CN=Users,DC=test,DC=com",
"bindPassword": "password123",
"searchDn": "OU=UserContainer,DC=test,DC=com",
"searchStandard": "mail"
}
}
2
3
4
5
6
7
8
9
10
# 1.2 LDAP的主要产品
细心的朋友应该会主要到,LDAP的中文全称是:轻量级目录访问协议,说到底LDAP仅仅是一个访问协议,那么我们的数据究竟存储在哪里呢?
来,我们一起看下下面的表格:
厂商 | 产品 | 介绍 |
---|---|---|
SUN | SUNONE Directory Server | 基于文本数据库的存储,速度快 。 |
IBM | IBM Directory Server | 基于DB2 的的数据库,速度一般。 |
Novell | Novell Directory Server | 基于文本数据库的存储,速度快, 不常用到。 |
Microsoft | Microsoft Active Directory | 基于WINDOWS系统用户,对大数据量处理速度一般,但维护容易,生态圈大,管理相对简单。 |
Opensource | Opensource | OpenLDAP 开源的项目,速度很快,但是非主 流应用。 |
没错,这就是正常存储数据的地方,而访问这些数据就是通过我们上述所说的LDAP。相信到这里大家应该了解两者之间的关系了吧!
# 1.3 LDAP的基本模型
每一个系统、协议都会有属于自己的模型,LDAP也不例外,在了解LDAP的基本模型之前我们需要先了解几个LDAP的目录树概念:
(一)目录树概念
- 目录树:在一个目录服务系统中,整个目录信息集可以表示为一个目录信息树,树中的每个节点是一个条目。
\2. 条目:每个条目就是一条记录,每个条目有自己的唯一可区别的名称(DN)。
- 对象类:与某个实体类型对应的一组属性,对象类是可以继承的,这样父类的必须属性也会被继承下来。
- 属性:描述条目的某个方面的信息,一个属性由一个属性类型和一个或多个属性值组成,属性有必须属性和非必须属性。
(二)DC、UID、OU、CN、SN、DN、RDN
关键字 | 英文全称 | 含义 |
---|---|---|
dc | Domain Component | 域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com(一条记录的所属位置) |
uid | User Id | 用户ID songtao.xu(一条记录的ID) |
ou | Organization Unit | 组织单位,组织单位可以包含其他各种对象(包括其他组织单元),如“oa组”(一条记录的所属组织) |
cn | Common Name | 公共名称,如“Thomas Johansson”(一条记录的名称) |
sn | Surname | 姓,如“许” |
dn | Distinguished Name | “uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一) |
rdn | Relative dn | 相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson” |
(三)基本模型:
- 信息模型:
命名模型:
功能模型:
安全模型:
四、LDAP的使用
那我们是如何访问LDAP的数据库服务器呢?
统一身份认证主要是改变原有的认证策略,使需要认证的软件都通过LDAP进行认证,在统一身份认证之后,用户的所有信息都存储在AD Server中。终端用户在需要使用公司内部服务的时候,都需要通过AD服务器的认证。
那么程序中是如何访问的呢? 我们以PHP脚本作为例子:
$ldapconn = ldap_connect(“10.1.8.78") $ldapbind = ldap_bind($ldapconn, 'username', $ldappass); $searchRows= ldap_search($ldapconn, $basedn, "(cn=*)"); $searchResult = ldap_get_entries($ldapconn, $searchRows); ldap_close($ldapconn);
- 连接到LDAP服务器;
- 绑定到LDAP服务器;
- 在LDAP服务器上执行所需的任何操作;
- 释放LDAP服务器的连接;
# 2. openldap
openldap官网
django实现登录流程对应的代码
linux部署openldap详细
# 2.1 OpenLDAP目录架构
# 1. OpenLDAP目录架构介绍
目前OpenLDAP目录架构分为两种:一种为互联网命名组织架构;另一种为企业级命名组织架构。本节分别为介绍两种架构的用途,但本书主要以企业级命名组织架构为核心进行阐述OpenLDAP内部逻辑结构、工作原理以及企业实践等相关知识。
# 2. 互联网命名组织架构
LDAP的目录信息是以树形结构进行存储的,在树根一般定义国家(c=CN)或者域名(dc=com),其次往往定义一个或多个组织(organization,o)或组织单元(organization unit,ou)。一个组织单元可以包含员工、设备信息(计算机/打印机等)相关信息。例如uid=babs,ou=People,dc=example,dc=com,如图1-2所示。
# 3. 企业级命名组织架构
企业级命名组织架构的示例如图1-3所示。
# 4. OpenLDAP的系统架构
OpenLDAP目前是一款开源账号集中管理软件,且属于C/S架构(见图1-4)。通过配置服务器和客户端,实现账号的管理,并通过与第三方应用相结合,实现客户端所有账号均可通过服务端进行验证,例如Samba、Apache、Zabbix、FTP、Postfix、EMC存储以及系统登录验证并授权。
# 5. OpenLDAP的工作模型
OpenLDAP的工作模型如图1-5所示。
OpenLDAP工作模型解释如下:
客户端向OpenLDAP服务器发起验证请求;服务器接收用户请求后,并通过slapd进程向后端的数据库进行查询;slapd将查询的结果返回给客户端即可。如果有缓存机制,服务器端会先将查询的条目进行缓存,然后再发给客户端。
# 3. 如何使用Python连接ldap
https://www.cnblogs.com/linxiyue/p/10250243.html
好多使用ldap认证的软件都是Python的,比如superset和airflow, 好吧,他们都是airbnb家的。在配置ldap的时候可能会出现认证失败,你不知道是因为什么导致配置失败的。所以,就要跟踪源码,看看内部怎么认证实现的。
ldap介绍和使用安装参见: https://www.cnblogs.com/woshimrf/p/ldap.html
登录的源码参见: https://github.com/apache/airflow/blob/70e937a8d8ff308a9fb9055ceb7ef2c034200b36/airflow/contrib/auth/backends/ldap_auth.py#L191
具体来实现如下:
为了模拟环境,我们使用docker-python。基于Debian Python3: https://github.com/Ryan-Miao/docker-china-source/tree/master/docker-python
启动
docker run -it ryan/python:3 /bin/bash
下载ldap3
pip install ldap3
LDAP(Light Directory Access Portocol)是轻量目录访问协议,基于X.500标准,支持TCP/IP。
LDAP目录以树状的层次结构来存储数据。每个目录记录都有标识名(Distinguished Name,简称DN),用来读取单个记录,一般是这样的:
几个关键字的含义如下:
- base dn:LDAP目录树的最顶部,也就是树的根,是上面的dc=test,dc=com部分,一般使用公司的域名,也可以写做o=test.com (opens new window),前者更灵活一些。
- dc::Domain Component,域名部分。
- ou:Organization Unit,组织单位,用于将数据区分开。
- cn:Common Name,一般使用用户名。
- uid:用户id,与cn的作用类似。
- sn:Surname, 姓。
- rdn:Relative dn,dn中与目录树的结构无关的部分,通常存在cn或者uid这个属性里。
所以上面的dn代表一条记录,代表一位在test.com公司people部门的用户username。
# python-ldap
python一般使用python-ldap库操作ldap,文档:https://www.python-ldap.org/en/latest/index.html。
下载:
还要安装一些环境,ubuntu:
CentOS:
获取LDAP地址后即可与LDAP建立连接:
绑定用户,可用于用户验证,用户名必须是dn:
成功认证时会返回一个tuple:
验证失败会报异常ldap.INVALID_CREDENTIALS:
注意验证时传空值验证也是可以通过的,注意要对dn和pwd进行检查。
查询LDAP用户信息时,需要登录管理员RootDN帐号:
添加用户add_s(dn, modlist),dn为要添加的条目dn,modlist为存储信息:
添加成功会返回元组:
失败会报ldap.LDAPError异常
# 4. Django使用LDAP验证
参考文章
[原创]django+ldap实现统一认证部分一(django-auth-ldap实践) - 相关文章 (opens new window)
简要流程
登录时,在默认的django数据库 (opens new window)帐号验证之前,会先到LDAP服务器上去验证。 输入的登录帐号到LDAP服务器验证之前,会先用配置文件中的绑定DN、密码去验证,验证通过才能继续用输入的帐号密码去LDAP服务器验证。 若LDAP验证通过,会检查django数据库中是否已存在该帐号,若不存在,则会根据LDAP验证通过后获取的用户信息,来创建django数据库的用户账号。帐号名和输入的一样,密码则会设为一个无效的密码(看了下源码是”!”,无法合法哈希编码),因为该帐号密码验证是从LDAP上进行,所以django中的密码不会被使用到。除了默认的用户姓名、邮件等信息,若要把Group信息也同步过来的话需要进行相应的配置。 若LDAP验证失败,则会使用Django数据库的默认登录验证。
ldap认证实现思路
如果一个项目的用户登陆要通过ldap,那么这个项目一般就是公司内部项目,例如OA系统,运维平台等。那么,我们可以将用户输入账号、密码信息发给ldap服务器进行认证。如果ldap认证通过,我们去查询数据库中是否已存在此账号的用户,若存在,直接跳转登陆即可,若不存在,则先在数据库中创建此用户,随后跳转登陆。如果ldap认证失败,提示错误信息并返回登陆页即可。有了这样的思路,我们的代码就很简单了。
Authentication - django-auth-ldap 4.1.1.dev6+ga6e03c6.d20220907 documentation (opens new window)
Django集成LDAP认证有现成的django-auth-ldap
模块可以使用,本文也主要以这个模块的使用为主,先安装模块
- LDAP中存用户的DN值(distinguished name即唯一值),DN值目测有3种方式组成:
LDAP中存用户的DN值(distinguished name即唯一值),DN值目测有3种方式组成:
a. uid=用户名,ou=LDAP组,dc=域名,dc=com或者cn,举例 uid=admin,ou=system,dc=eoncloud,dc=com
b. cn=用户名,ou=LDAP组,dc=域名,dc=com或者cn, 举例cn=admin,ou=system,dc=eoncloud,dc=com
c. sAMAccountName=用户,ou=LDAP组,dc=域名,dc=com或者cn; sAMAccountName要结合AD域用,我司LDAP没用AD域,此处忽略
与LDAP管理员确认我司用uid方式生成DN值,那么django配置文件里面相应的配置项就用uid
为什么要分清楚DN呢,是因为任何系统登录时会录入username+password,而username就是用来组成DN的;应用系统生成DN(含username)值+password发到LDAP去匹配,匹配上了LDAP会返回给应用经过鉴权的用户信息,进而登录到应用系统中;当然,此username+password事先已经存在于LDAP中的,鉴权成功的服务端日志打印如下:
Created Django user xxxx
Populating Django user xxxx
[17/Nov/2017 14:06:40] "POST /accounts/login/ HTTP/1.1" 302 0
2
3
4
5
6
7
8
9
# 4.1 django中ldap验证的三种方式
# 方法一:settings
django中settings添加ldap验证及自动记录用户信息到本地user表中
# settings配置
import ldap
from django_auth_ldap.config import LDAPSearch
AUTHENTICATION_BACKENDS = (
# 配置为先使用LDAP认证,如通过认证则不再使用后面的
'django_auth_ldap.backend.LDAPBackend',
# 本地用户验证,如果不需要的,可以注释掉
'django.contrib.auth.backends.ModelBackend',
)
base_dn = 'dc=baidu,dc=com' # ldap的域名信息(例如baidu.com,可以拆分为baidu跟com)
AUTH_LDAP_SERVER_URI = 'ldap://xxx.xxx.xxx.xxx:389' # ldap服务器地址及端口
AUTH_LDAP_BIND_DN = 'xxx@baidu.com' # 用户名,可以使用自己的用户名,用户名后面要加上域名
AUTH_LDAP_BIND_PASSWORD = 'xxx' # 对应用户名的密码
# LDAPSearch参数1:搜索的用户信息,ou是组织,后面格式化输出的是你的用户名信息,
# 参数2:默认,参数3:搜索的用户,我使用的user,有的公司是uid,如果不知道,可以尝试下
AUTH_LDAP_USER_SEARCH = LDAPSearch('ou=你的组织,%s' % base_dn, ldap.SCOPE_SUBTREE, "(SamAccountName=%(user)s)")
AUTH_LDAP_ALWAYS_UPDATE_USER = True
# key为数据库字段名,value为ldap中字段名,此字典解决django model与ldap字段名可能出现的不一致问题
# 例如:用户名,在自己django的user表中字段是username,但是在ldap中字段是sAMAccountName,利用此配置可以同步
AUTH_LDAP_USER_ATTR_MAP = {
"username": "sAMAccountName",
"name": "physicalDeliveryOfficeName",
"email": "mail",
'title': 'title',
'company': 'company',
'department': 'department',
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
用户登录的时候使用默认的认证类
# 用户登录view
from rest_framework.response import Response
from rest_framework.views import APIView
from django.contrib.auth import authenticate
class Login(APIView):
def post(self, request):
username = request.data.get('username', None)
password = request.data.get('password', None)
# 先验证ldap账户,如果不存在,则会验证本地用户
ldap_user = authenticate(username=username, password=password)
# 验证通过后,可以看到,本地user表中,会自动添加一条同步的用户信息
if ldap_user:
return Response(
{'code': 200, 'uid': ldap_user.id, 'name': ldap_user.name, 'department': ldap_user.department}
)
return Response({'code': 405, 'message': '用户名或密码错误'})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 方法二:ldap3
这是一种更加简单的,适用与验证该用户是否存在的ldap认证方式,通过用户输入的信息直接连接ldap去当中获取,获取成功则登录成功。
from ldap3 import Server, Connection, ALL, NTLM
def new_auth_user(username, password):
# 链接服务,参数一:服务器ip
server = Server('xxx.xxx.xxx.xxx', get_info=ALL)
# user中要拼接用户的域,例如,域名是baidu.com,则可以修改为:'baidu\\\\' + username
conn = Connection(server, user='baidu\\\\' + username, password=password, auto_bind=True, authentication=NTLM)
# 配置搜索的组织及域名,例如域名为baidu.com,则可以如下配置。第二个参数,需要搜索的用户名,
# 第三个参数,搜索用户的信息,*代表所搜该用户的所有信息,可以根据需要进行修改,必定很多信息我们用不到
conn.search('ou=你的组织,dc=baidu,dc=com', '(SamAccountName=搜索的用户名)', attributes=['*'])
result = conn.entrie
print(result)
2
3
4
5
6
7
8
9
10
11
12
# 方法三:ldap
此方法只能认证用户是否存在
import ldap
def auth_user(username, password):
conn = ldap.initialize(ldap服务器地址:'xxx.xxx.xxx.xxx:389')
try:
# 将username附加上域名
username += '@xxxxx.com'
# 验证用户是否存在,存在返回1,不存在,则会报错
conn.simple_bind_s(username, password)
return 1
except Exception as e:
return e
2
3
4
5
6
7
8
9
10
11
12
# 基于现在登录操作实现思路
1. 用户调用登录接口,输入(用户名或邮箱、密码) cabits中id和username是唯一的。可以将id和username存入域中
2. 通过ldap3模块连接到openldap服务
server = Server('ldaps://10.1.1.100', get_info=ALL, use_ssl=True) # 连接服务
3. 通过用户输入的信息,连接服务器,拼接域进行提取信息
c = Connection(server, auto_bind=True, user="qytang\\\\"+ad_admin_username, password=ad_admin_password) # 连接服务器
# 提取域qytang.com, 用户的memberOf,sn和department信息
c.search(search_base='dc=qytang,dc=com', search_filter='(&(samAccountName=' + username + '))', attributes=['sn', 'department', 'createTimeStamp', 'accountExpires', 'userAccountControl', 'objectClass', 'pwdLastSet'], paged_size=5)
3.1 在域中提取信息成功,则返回对应的信息(username等一些属性信息)
a. 用户username或者id等一些唯一的信息。在获取一次本地的数据库 使用create_or_update方法看是否有修改的。获取到对象信息生成token并返回
3.2 在域中没有找到
a. 用户用户输入的信息去本地的数据中查找,本地的数据中查找到,则向服务中添加一个用户域
c = Connection(server, auto_bind=True, user="qytang\\\\"+ad_admin_username, password=ad_admin_password)
c.add(user_dn, attributes={'objectClass': ['top', 'person', 'organizationalPerson', 'user'],'sAMAccountName': add_username,})
需要在域中绑定id 还是 绑定username password
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.2 django配置
# 1. 安装依赖
pip install python-ldap django-auth-ldap
# 2. 配置django的settings.py文件
加入 django_python3_ldap
INSTALLED_APPS **+=** [
'django_python3_ldap',
]
#Django-auth-ldap 配置部分
import ldap
from django_auth_ldap.config import LDAPSearch,GroupOfNamesType
#修改Django认证先走ldap,再走本地认证
AUTHENTICATION_BACKENDS = [
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
]
#ldap的连接基础配置
AUTH_LDAP_SERVER_URI = "ldap://xxx.xxx.xxx.xxx:389"
# ldap or ad 服务器地址AUTH_LDAP_BIND_DN = "CN=administrator,CN=Users,DC=test,DC=com" # 管理员的dn路径AUTH_LDAP_BIND_PASSWORD = 'testpassword' # 管理员密码#允许认证用户的路径
AUTH_LDAP_USER_SEARCH = LDAPSearch("OU=test,DC=test,DC=intra",ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)") # 第一个参数是搜索的范围
#通过组进行权限控制
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=groups,ou=test,dc=test,dc=intra",
ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)")
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
#is_staff:这个组里的成员可以登录;is_superuser:组成员是django admin的超级管理员;is_active:组成员可以登录django admin后台,但是无权限查看后台内容
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
"is_staff": "cn=test_users,ou=groups,OU=test,DC=test,DC=com",
"is_superuser": "cn=test_users,ou=groups,OU=tset,DC=test,DC=com",
}#通过组进行权限控制end
#如果ldap服务器是Windows的AD,需要配置上如下选项
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_DEBUG_LEVEL: 1,
ldap.OPT_REFERRALS: 0,
}
# key为数据库字段名,value为ldap中字段名,此字典解决django model与ldap字段名可能出现的不一致问题
# 例如:用户名,在自己django的user表中字段是username,但是在ldap中字段是sAMAccountName,利用此配置可以同步
AUTH_LDAP_USER_ATTR_MAP = {
"username": "sAMAccountName",
"name": "physicalDeliveryOfficeName",
"email": "mail",
'title': 'title',
'company': 'company',
'department': 'department',
}
#如果为True,每次组成员都从ldap重新获取,保证组成员的实时性;反之会对组成员进行缓存,提升性能,但是降低实时性# AUTH_LDAP_FIND_GROUP_PERMS = True
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 一个很简单的LDAP验证Backend:
import ldap
class LDAPBackend(object):
"""
Authenticates with ldap.
"""
_connection = None
_connection_bound = False
def authenticate(self, username=None, passwd=None, **kwargs):
if not username or not passwd:
return None
if self._authenticate_user_dn(username, passwd):
user = self._get_or_create_user(username, passwd)
return user
else:
return None
@property
def connection(self):
if not self._connection_bound:
self._bind()
return self._get_connection()
def _bind(self):
self._bind_as(
LDAP_CONFIG['USERNAME'], LDAP_CONFIG['PASSWORD'], True
)
def _bind_as(self, bind_dn, bind_password, sticky=False):
self._get_connection().simple_bind_s(
bind_dn, bind_password
)
self._connection_bound = sticky
def _get_connection(self):
if not self._connection:
self._connection = ldap.initialize(LDAP_CONFIG['HOST'])
return self._connection
def _authenticate_user_dn(self, username, passwd):
bind_dn = 'cn=%s,%s' % (username, LDAP_CONFIG['BASE_DN'])
try:
self._bind_as(bind_dn, passwd, False)
return True
except ldap.INVALID_CREDENTIALS:
return False
def _get_or_create_user(self, username, passwd):
# 获取或者新建User
return user
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
不想自己写的话,django与flask都有现成的库:
django-ldap (opens new window)
账号管理
cn=admin,dc=hongpu,dc=com
hongpu.8192
2
3
https://blog.csdn.net/u011607971/article/details/117824558
docker run p 389:389 p 636:636 --name youe_ldap --network bridge --hostname openldap-host --env LDAP_ORGANISATION="youedata" --env LDAP_DOMAIN="youedata.com" --env LDAP_ADMIN_PASSWORD="youedata520" --detach osixia/openldap
————————————————
版权声明:本文为CSDN博主「李小虾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:<https://blog.csdn.net/monkeyblog/article/details/94021802>
2
3
4
LDAP使用docker安装部署与使用_啧啧zzz的博客-CSDN博客 (opens new window)
docker run -p 389:389 -p 636:636 --name your_ldap --network bridge --hostname openldap-host --env LDAP_ORGANISATION="example" --env LDAP_DOMAIN="example.com (opens new window)" --env LDAP_ADMIN_PASSWORD="123456" --detach osixia/openldap
docker run -d --privileged -p 8080:80 --name youe_pla --env PHPLDAPADMIN_HTTPS=false --env PHPLDAPADMIN_LDAP_HOSTS=0.0.0.0 --detach osixia/phpldapadmin
# slappasswd
New password: Re-enter new password: {SSHA}s6p0UB2LhW3rZrEm/z5vqUjmPD1AadUR
docker run -p 6443:80 --env PHPLDAPADMIN_HTTPS=false PHPLDAPADMIN_LDAP_HOSTS=0.0.0.0 -itd --name phpldapadmin osixia/phpldapadmin:0.9.0
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f root.ldif
# 添加ldif文件
<https://www.jianshu.com/p/cce418c6a745>
为解决问题