我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python对接LDAP/AD的过程详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python对接LDAP/AD的过程详解

不同公司的 LDAP/AD 服务配置各不相同,很难封装一个通用的方法,所以我们在对接 LDAP/AD 的过程中,需要了解自己公司的 LDAP/AD 服务配置是怎么样的,才能写出正确的对接代码,因此下面将拆解过程并提供相关的文档地址。

首先需要了解一些 LDAP/AD 的基本概念:

  • dc:域名的部分,其格式是将完整的域名分成几部分,如域名为 example.com 变成 dc=example,dc=com(一条记录的所属位置)
  • uid:用户ID
  • ou:组织单位,组织单位可以包含其他各种对象(包括其他组织单元)
  • cn:公共名称
  • sn:姓
  • dn:一条记录的位置(唯一)
  • rdn:相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分

Python 对接 LDAP 目前主要有两个库,ldap3python-ldap 库:

库名称实现语言接口风格
ldap3纯Python偏向对象
python-ldap混合C+Python偏向过程

综上对比,推荐使用 ldap3 实现 LDAP 对接:

pip install ldap3

首先通过 PIP 安装 ldap3 库,并导入相关类到代码中:

from ldap3 import Server, Connection, ALL

通过 LDAP 服务器地址创建一个 LDAP 服务对象:

server = Server('127.0.0.1', get_info=ALL)print(server)# Server(host='127.0.0.1', port=389, use_ssl=False, allowed_referral_hosts=[('*', True)], get_info='ALL', mode='IP_V6_PREFERRED')

观察 LDAP 服务对象的输出信息:

输出信息含义
host=‘127.0.0.1’LDAP 服务器 IP 或 URL
port=389服务端口,默认就是 389 端口
use_ssl=False是否使用 SSL,如果为 True,意味需要 建立安全连接
allowed_referral_hosts=[(‘*’, True)]限定允许请求的主机
get_info=‘ALL’是否必须读取服务器架构和服务器特定信息
mode=‘IP_V6_PREFERRED’用于解析 DNS 中的 LDAP 服务器名称的双 IP 堆栈行为

更详细的配置及其含义可以查看 LDAP 服务对象 (server-object) 文档。

使用 LDAP 服务对象,基于一个公用账号(使用公有账号可以确保服务稳定)建立 LDAP 连接:

conn = Connection(server, user='Domain\\User', password='password', auto_bind=True, raise_exceptions=True)print(conn)# Connection(server=Server(host='127.0.0.1', port=389, use_ssl=False, allowed_referral_hosts=[('*', True)], get_info='ALL', mode='IP_V6_PREFERRED'), user='Domain\\User', password='password', auto_bind='NO_TLS', version=3, authentication='SIMPLE', client_strategy='SYNC', auto_referrals=True, check_names=True, read_only=False, lazy=False, raise_exceptions=False, fast_decoder=True, auto_range=True, return_empty_attributes=True, auto_encode=True, auto_escape=True, use_referral_cache=False)

观察 LDAP 连接对象的输出信息:

输出信息含义
user=‘Domain\User’绑定的用户的帐户
password=‘password’绑定的用户密码
auto_bind=‘NO_TLS’自动打开并绑定连接
version=3LDAP 协议版本
authentication=‘SIMPLE’身份验证方法
client_strategy=‘SYNC’客户端使用的通信策略
auto_referrals=True指定连接是否服务器中允许的
check_names=True搜索结果将按照结构中指定的格式进行格式化
read_only=FalseTrue 时禁止修改、删除、添加等操作
lazy=FalseTrue 时连接将延迟打开和绑定,直到请求另一个 LDAP 操作
raise_exceptions=FalseTrue 时引发 LDAPOperationResult 的异常
fast_decoder=TrueFalse 时使用 pyasn1 解码器而不是内部解码器

更详细的配置及其含义可以查看 LDAP 连接对象 (Connection) 文档。

到这一步的时候,可以询问 LDAP 服务器当前连接用户是谁?简单验证一下连接有效性:

conn.extend.standard.who_am_i()# 'u:Domain\\User'

使用公用账号查询某个用户的 SAMAccountName 信息是否存在:

result = conn.search(search_base='OU=OU,DC=Domain,DC=LOCAL', search_filter='(sAMAccountName=xiaoming)')# True

观察 LDAP 连接对象的 search() 函数输入/输出信息:

  • 输入
    • search_base = 搜索用户的基础路径
    • search_filter = 过滤 LDAP 用户的过滤器语句
      • sAMAccountName = 用于存储账户登录名或用户符号,实际上是命名符号 Domain\LogonName,该属性是域用户对象的必需属性
  • 输出
    • result = True 表示用户存在,否则用户不存在

如果上一步的用户查询成功,即结果为 True,下面就可以查看其 response 信息,获取查询到的用户详细信息:

conn.response# [{'raw_dn': b'CN=\xbd...,DC=LOCAL', 'dn': 'CN=小明-10001001,OU=自动化测试组,OU=测试部,OU=研发中心,OU=Domain,OU=行政组织,OU=OU,DC=LEEDARSON,DC=LOCAL', 'raw_attributes': {}, 'attributes': {}, 'type': 'searchResEntry'}]

上面返回的用户 dn 信息有两种:

  • raw_dn 原始信息
    conn.response[0]['raw_dn'].decode('UTF-8')# 'CN=小明-10001001,OU=自动化测试组,OU=测试部,OU=研发中心,OU=Domain,OU=行政组织,OU=OU,DC=LEEDARSON,DC=LOCAL'
  • dn 可读信息
    conn.response[0]['dn']# 'CN=小明-10001001,OU=自动化测试组,OU=测试部,OU=研发中心,OU=Domain,OU=行政组织,OU=OU,DC=LEEDARSON,DC=LOCAL'

不管是那种格式,信息本身的内容是一样的。默认情况下使用 user_dn = conn.response[0]['dn'] 获取用户 dn 信息就可以。

接下来就使用用户 dn 信息去验证用户的密码是否正确,如果密码正确,就和前面公用账号登录一样可以获取用户信息。如果登录异常,我们可以根据响应内容判断具体异常的原因:

from ldap3.core.exceptions import LDAPInvalidCredentialsResulttry:    Connection(server, user=user_dn, password='password', auto_bind=True, raise_exceptions=True)except LDAPInvalidCredentialsResult as e:    if '52e' in e.message:        print('账号密码不正确')    elif '775' in e.message:        print('账号已锁定,请联系管理员或等待自动解锁')    elif '533' in e.message:        print('账号已禁用')    else:        print('认证失败,请联系管理员检查该账号')

更多具体的情况,就需要实际对接公司的 LDAP/AD 服务时,才会遇到了。

来源地址:https://blog.csdn.net/hekaiyou/article/details/128961940

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python对接LDAP/AD的过程详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringBoot对接Spark过程详解

这篇文章主要介绍SpringBoot接入Spark的方法的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望能帮助大家解决问题
2023-02-15

详解Java的面向对象和面向过程

我们知道,Java是面向对象的编程语言,但是至今仍有不少同学还不太懂”面向对象“的确切含义,今天这篇文章就带大家真正地认识面向对象,感兴趣的同学可以跟着小编一起来学习
2023-05-20

Kotlin引用其他xml的view对象过程详解

这篇文章主要介绍了Kotlin中如何引用其他xml中的view对象,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2023-02-16

PHP面向对象和面向过程的区别详解

面向对象(OOP)和面向过程(POP)是编程中不同的范例,用于组织代码。OOP以对象为中心,强调封装、继承和多态性,提高代码的可重用性和灵活性。POP以过程为中心,强调代码的顺序和流程。OOP适用于复杂系统、可重用性高或灵活性要求高的场景,而POP更适合简单任务、速度和效率优先的场景。
PHP面向对象和面向过程的区别详解
2024-04-02

关于Python中对变量赋值过程的理解

在Python中对变量赋值过程的理解,有助于学习者对Python的变量和所指向的对象之间的指向关系深刻理解,避免编程中多个变量赋值后,对变量结果的不确定,,需要的朋友可以参考下
2023-05-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录