LDAP 编程 (Python)
您可能听说过下一代目录协议 LDAP(轻型目录访问协议),并且想知道是否可以编写程序与之交互。也许您甚至已经设置了自己的 LDAP 服务器,现在想为其编写程序。为了实现这些目标,本文将帮助您准备好编写自己的程序,以自动化 LDAP 服务器的查询过程。希望它还能为您扩展知识以编写配置脚本以及您想使用 LDAP 做的任何其他事情奠定坚实的基础。
大多数主要的编程语言都有 LDAP API,但我选择使用 Python,因为它可能是最容易和最清晰的演示语言。如果您还不了解 Python 编程语言和 LDAP 的基础知识,您可能应该在更好地熟悉它们之后再回到本教程。
使用 Python 和 python-ldap 编写访问 LDAP 服务器的程序很容易。python-ldap 包包含一个模块,该模块封装了 OpenLDAP C API,并提供了一个面向对象的客户端 API 来与 LDAP 目录服务器交互。该包还包含用于执行与 LDAP 相关的其他任务的模块,例如处理 LDIF、LDAPURLs 和 LDAPv3 方案等等。
目前,Python 的标准实现不包含 python-ldap,但您可以从 SourceForge 下载它作为第三方软件包。
学习的最佳方式是编写示例程序,因此让我们编写一个小而完整的程序,从 LDAP 服务器获取一些特定的联系信息。由于缩进在 Python 中很重要,因此下面给出的所有代码都已缩进,因此请按您看到的方式复制它。
我们需要做的第一件事是导入 ldap 模块。因此,打开您最喜欢的文本编辑器并键入 import ldap。对于这个程序,我们需要创建两个简单的函数
一个 main() 函数,将程序绑定到 LDAP 服务器并调用搜索函数
一个名为 my_search() 的函数,用于从服务器检索/显示数据。
让我们创建我们的 main 函数,并通过使用 def main(): 设置变量以向 LDAP 服务器进行身份验证。
如果您使用的是公共服务器,则可以将 who 和 cred 的值留空。您可以在这里获取一些公共 LDAP 服务器的列表
。它看起来像这样
server = "ldap.somewhere.edu" who = "" cred = ""
现在我们需要设置一个关键字,以确定我们想要的搜索字符串。在这个示例程序中,我使用我的名字
keyword = "ryan"
接下来,我们需要绑定到 LDAP 服务器。这样做会创建一个名为 “l” 的对象,然后在整个程序中使用该对象。
try: l = ldap.open(server) l.simple_bind_s(who, cred) print "Successfully bound to server.\n"
我们现在准备好查询服务器了。我们现在还捕获任何可能的错误,以防身份验证出现问题
print "Searching..\n" my_search(l, keyword) except ldap.LDAPError, error_message: print "Couldn't Connect. %s " % error_message
编写完 main 函数后,我们现在可以创建搜索函数了
def my_search(l, keyword):
稍后我们将在我们的 l 对象上调用 python-ldap 的内置搜索方法。四个变量——base、scope、filter 和 retrieve_attributes——是该搜索方法的参数。Base 用于搜索应开始的条目的 DN(专有名称)。对于此示例,您可以将其留空
base = ""
对于 scope,我们使用 SCOPE_SUBTREE 来搜索对象及其所有后代
scope = ldap.SCOPE_SUBTREE
我们的搜索过滤器由 cn(通用名称)和我们的关键字组成。在我们的关键字(ryan)周围加上星号将匹配任何包含字符串 ryan 的内容,例如 Bryant。
filter = "cn=" + "*" + keyword + "*"
我们传递给搜索方法的最后一个参数用于返回每个条目的所有属性
retrieve_attributes = None
现在,让我们设置更多变量,包括一个计数器来跟踪返回的结果数
count = 0
一个用于附加结果的列表
result_set = []
以及一个变量,用于指定我们愿意等待服务器响应的时间长度(以秒为单位)
timeout = 0
现在我们可以通过在我们的 l 对象上调用 python-ldap 的搜索方法来开始搜索
try: result_id = l.search(base, scope, filter, retrieve_attributes)
将任何结果存储在 result_set 列表中
while 1: result_type, result_data = l.result(result_id, timeout) if (result_data == []): break else: if result_type == ldap.RES_SEARCH_ENTRY: result_set.append(result_data)
如果我们现在要打印 result_set,它可能看起来像一个包含元组和字典的大列表。相反,逐步遍历它,只选择我们想要查看的数据
if len(result_set) == 0: print "No Results." return for i in range(len(result_set)): for entry in result_set[i]: try: name = entry[1]['cn'][0] email = entry[1]['mail'][0] phone = entry[1]['telephonenumber'][0] desc = entry[1]['description'][0] count = count + 1
如果找到数据,则以以下格式显示数据
1. 姓名: 描述: 电子邮件: 电话: 2. 姓名: 描述: 电子邮件: 电话: 等等..
print "%d.\nName: %s\nDescription: %s\nE-mail: %s\nPhone: %s\n" %\ (count, name, desc, email, phone) except: pass except ldap.LDAPError, error_message: print error_message
您现在可能很想运行该程序并查看它的实际效果。但首先,您需要附加以下代码来调用 main() 函数。它应该在您运行脚本之前放在脚本的末尾。
if __name__=='__main__': main()
既然您已经输入了运行 Python 程序所需的一切,请将源代码保存在您的编辑器中,并将文件命名为 ldap-test.py。运行它并进行测试。如果您没有看到任何输出,可能是因为您没有输入有效的 LDAP 服务器和/或 who 和 cred,或者仅仅是因为服务器上没有与我们正在使用的搜索字段(在本例中为 *ryan*)匹配的字段。
我们只是初步了解了如何使用 Python 编写 LDAP 应用程序;您可以使用 python-ldap 做更多的事情。您可以在这里找到更多 python-ldap 编程示例。
有关更多信息,请查看 python-ldap 文档。 与 LDAP 相关的 RFC 的完整列表也可以在线免费获得。如果您正在寻找一本好书,请考虑 Clayton Donely 的 LDAP 编程、管理和集成 和 Tim Howes 的 LDAP:使用轻型目录访问协议进行目录启用应用程序编程。这些书使用 C/C++、Perl 和 Java 等编程语言作为其代码示例,但对于那些希望用 Python 编写 LDAP 应用程序的人来说,它们仍然很有帮助。对于 LDAP 的 开源 实现,请访问 OpenLDAP 的网站。还有一个 开发人员邮件列表。
电子邮件:ambiod@sbcglobal.net