您的位置:

使用Pythonldap3进行LDAP开发

使用Pythonldap3进行LDAP开发

更新:

一、Pythonldap3概述

Pythonldap3是Python 3的LDAP接口库,Pythonldap3实现了RFC4511定义的LDAP协议的所有操作和功能,它具有易学易用、高性能的特点,能够轻松地连接LDAP服务和对LDAP目录执行增、删、改、查等操作。

二、Pythonldap3的安装

在安装Pythonldap3之前,需要确保已经安装了Python 3,可以通过以下命令检查Python版本:

python --version

安装Pythonldap3可以通过pip工具来进行,可以使用以下命令安装Pythonldap3:

pip install pythonldap3

三、Pythonldap3连接LDAP服务器

连接LDAP服务器是使用Pythonldap3进行LDAP开发的第一步。Pythonldap3提供了两种方式来连接LDAP服务器——LDAP URL连接和自定义连接。

1. LDAP URL连接

使用标准LDAP URL的形式来连接LDAP服务器。LDAP URL格式为:

ldap[s]://[hostname/ip][:port]/dn?[attributes][?scope][?filter]

其中:

  • ldap[s]://:指定连接方式,使用LDAP协议的话,使用ldap://,如果使用LDAP over SSL协议,使用ldaps://
  • hostname/ip:指定LDAP服务器IP地址或主机名。
  • port:指定连接的端口号。
  • dn:指定连接目录的根节点DN。
  • attributes:指定从LDAP目录中返回的属性值。
  • scope:指定LDAP查询范围。
  • filter:指定LDAP查询过滤条件。

示例代码如下:

from ldap3 import Server, Connection

# LDAP URL连接方式
url = 'ldap://ldap://192.168.0.1:389/dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(url)

# 创建LDAP连接
conn = Connection(server, user='cn=admin,dc=example,dc=com', password='admin', auto_bind=True)

# 测试连接
if conn.bind():
    print('LDAP connection successful')
else:
    print('LDAP connection failed')

2. 自定义连接

自定义连接方式需要指定LDAP服务器的一些详细信息,包括LDAP服务器的 IP、连接端口、绑定信息等,示例代码如下:

from ldap3 import Server, Connection, ALL

# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)

# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)

# 测试连接
if conn.bind():
    print('LDAP connection successful')
else:
    print('LDAP connection failed')

四、Pythonldap3的增、删、改、查操作

Pythonldap3提供了方便易用的API,能够轻松地完成更改LDAP目录的操作,以下是Pythonldap3的增、删、改、查操作的介绍。

1. 增加操作

增加操作就是将一个新条目插入到LDAP目录中。示例代码如下:

from ldap3 import Server, Connection, ALL, ObjectDef, AttrDef, AttrList, ALL_ATTRIBUTES, MODIFY_ADD

# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)

# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)

# 定义对象模式和属性
person_def = ObjectDef('person', 'ou=people,' + base_dn, conn)
person_def.add(AttrDef('objectclass', ['top', 'person']))
person_def.add(AttrDef('uid', ['auto_uid']))
person_def.add(AttrDef('cn', ['test user']))
person_def.add(AttrDef('mail', ['test@example.com']))

# 创建属性列表对象
attrs = AttrList()
attrs.add(person_def)

# 将对象加入LDAP目录中
conn.add(person_def.dn, attrs=attrs)

print('Add operation successful')

2. 删除操作

删除操作就是将一个指定的条目从LDAP目录中移除。示例代码如下:

from ldap3 import Server, Connection, ALL, MODIFY_DELETE

# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)

# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)

# 删除条目
conn.delete('cn=test user,ou=people,' + base_dn)

print('Delete operation successful')

3. 修改操作

修改操作就是在LDAP目录中修改一个特定的条目。示例代码如下:

from ldap3 import Server, Connection, ALL, ObjectDef, AttrDef, AttrList, ALL_ATTRIBUTES, MODIFY_REPLACE

# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)

# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)

# 定义对象模式和属性
person_def = ObjectDef('person', 'ou=people,' + base_dn, conn)
person_def.add(AttrDef('objectclass', ['top', 'person']))
person_def.add(AttrDef('uid', ['auto_uid']))
person_def.add(AttrDef('cn', ['test user']))
person_def.add(AttrDef('mail', ['test@example.com']))
person_def.add(AttrDef('description', ['old description']))

# 创建属性列表对象
attrs = AttrList()
attrs.add(person_def)

# 将对象加入LDAP目录中
conn.add(person_def.dn, attrs=attrs)

# 修改条目
conn.modify('cn=test user,ou=people,' + base_dn, {'description': [(MODIFY_REPLACE, ['new description'])]})

print('Modify operation successful')

4. 查询操作

查询操作通过使用LDAP查询语言(LDAP Query Language,LQL)来查询LDAP目录中的信息。Pythonldap3提供了两种查询操作方式——搜索操作和分页查询操作。

a. 搜索操作

搜索操作是指对LDAP目录进行查询操作。以下是Pythonldap3的搜索操作代码示例:

from ldap3 import Server, Connection, ALL, BASE, LEVEL, SUBTREE, DEREF_ALWAYS, Attribute, SEQUENCE_TYPES

# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)

# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)

# 搜索操作
search_base = 'ou=people,' + base_dn
search_filter = '(&(objectclass=person)(cn=test user))'
search_scope = SUBTREE
ret_attrs = ['cn', 'mail']
size_limit = 0
time_limit = 0
types_only = False
deref_aliases = DEREF_ALWAYS

# 查询条目
conn.search(search_base=search_base, search_filter=search_filter, search_scope=search_scope,
            attributes=ret_attrs, size_limit=size_limit, time_limit=time_limit, types_only=types_only, dereference_aliases=deref_aliases)

# 获取结果
for entry in conn.entries:
    print('CN:', entry.cn)

print('Search operation successful')

b. 分页查询操作

分页查询操作是指对LDAP目录进行查询操作,并且将查询结果分页返回。以下是Pythonldap3的分页查询操作代码示例:

from ldap3 import Server, Connection, ALL

# 自定义连接方式
host = '192.168.0.1'
port = 389
user = 'cn=admin,dc=example,dc=com'
password = 'admin'
base_dn = 'dc=example,dc=com'

# 创建LDAP服务器对象
server = Server(host=host, port=port, get_info=ALL)

# 创建LDAP连接
conn = Connection(server=server, user=user, password=password, client_strategy='SYNC', auto_bind=True)

# 分页查询操作
search_base = 'ou=people,' + base_dn
search_filter = '(objectclass=person)'

# 第一页查询
pagination_control = {'paged_criticality': True, 'paged_size': 10}
conn.search(search_base=search_base, search_filter=search_filter, attributes=['cn'], controls=pagination_control)

while True:
    # 打印查询结果
    for entry in conn.entries:
        print('CN:', entry.cn)

    # 获取下一页
    pagination_control_cookie = None
    for control in conn.response['controls']:
        if control.__class__.__name__ == 'SimplePagedResultsControl':
            pagination_control_cookie = control.cookie
            break

    if not pagination_control_cookie:
        break

    pagination_control['paged_cookie'] = pagination_control_cookie
    conn.search(search_base=search_base, search_filter=search_filter, attributes=['cn'], controls=pagination_control)

print('Pagination operation successful')