Ruby - LDAP 教程

Ruby/LDAP 是 Ruby 的扩展库。 它提供了一些 LDAP 库的接口,如 OpenLDAP、UMich LDAP、Netscape SDK、ActiveDirectory。

应用程序开发的通用 API 在 RFC1823 中进行了描述,并受 Ruby/LDAP 支持。


Ruby/LDAP 安装

您可以从 SOURCEFORGE.NET 下载并安装完整的 Ruby/LDAP 包。

在安装 Ruby/LDAP 之前,请确保您拥有以下组件 −

  • Ruby 1.8.x(如果你想使用 ldap/control,至少 1.8.2)。
  • OpenLDAP、Netscape SDK、Windows 2003 或 Windows XP。

现在,您可以使用标准的 Ruby 安装方法。 在开始之前,如果您想查看 extconf.rb 的可用选项,请使用"--help"选项运行它。

$ ruby extconf.rb [--with-openldap1|--with-openldap2| \
                   --with-netscape|--with-wldap32]
$ make
$ make install

注意 − 如果您在 Windows 上构建软件,您可能需要使用 nmake 而不是 make


建立 LDAP 连接

这是一个两步过程 −

步骤 1 − 创建连接对象

以下是创建与 LDAP 目录的连接的语法。

LDAP::Conn.new(host = 'localhost', port = LDAP_PORT)
  • host − 这是运行 LDAP 目录的主机 ID。 我们将其作为 localhost

  • port − 这是用于 LDAP 服务的端口。 标准 LDAP 端口是 636 和 389。确保您的服务器正在使用哪个端口,否则您可以使用 LDAP::LDAP_PORT。

此调用返回一个新的 LDAP::Conn 连接到服务器 host 的端口 port

步骤 2 − 绑定

这是我们通常指定用于会话其余部分的用户名和密码的地方。

以下是绑定 LDAP 连接的语法,使用 DN,dn,凭据,pwd,以及绑定方法,method

conn.bind(dn = nil, password = nil, method = LDAP::LDAP_AUTH_SIMPLE)do
....
end

您可以在没有代码块的情况下使用相同的方法。 在这种情况下,您需要显式取消绑定连接,如下所示 −

conn.bind(dn = nil, password = nil, method = LDAP::LDAP_AUTH_SIMPLE)
....
conn.unbind

I如果给定了一个代码块,self 就会让给该代码块。

如果我们拥有适当的权限,我们现在可以在 bind 方法的块内(在 bind 和 unbind 之间)执行搜索、添加、修改或删除操作。

示例

假设我们在本地服务器上工作,让我们将适当的主机、域、用户 ID 和密码等放在一起。

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')
....
conn.unbind

添加 LDAP 条目

添加 LDPA 条目是一个两步过程 −

步骤 1 − 创建 LDAP::Mod 对象

我们需要将 LDAP::Mod 对象传递给 conn.add 方法来创建条目。 这是创建 LDAP::Mod 对象的简单语法 −

Mod.new(mod_type, attr, vals)
  • mod_type −一个或多个选项 LDAP_MOD_ADD、LDAP_MOD_REPLACE 或 LDAP_MOD_DELETE。

  • attr − 应该是要操作的属性的名称。

  • vals − 是与 attr 相关的值数组。 如果 vals 包含二进制数据,则 mod_type 应与 LDAP_MOD_BVALUES 进行逻辑或 (|)。

此调用返回 LDAP::Mod 对象,该对象可以传递给 LDAP::Conn 类中的方法,例如 Conn#add、Conn#add_ext、Conn#modify 和 Conn#modify_ext。

步骤 2 − 调用 conn.add 方法

一旦我们准备好 LDAP::Mod 对象,我们就可以调用 conn.add 方法来创建一个条目。 这是调用此方法的语法 −

conn.add(dn, attrs)

此方法添加一个具有 DN、dn 和属性、attrs 的条目。 这里,attrs 应该是 LDAP::Mod 对象的数组或属性/值数组对的散列。

示例

这是一个完整的示例,它将创建两个目录条目 −

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
entry1 = [
   LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','domain']),
   LDAP.mod(LDAP::LDAP_MOD_ADD,'o',['TTSKY.NET']),
   LDAP.mod(LDAP::LDAP_MOD_ADD,'dc',['localhost']),
]

entry2 = [
   LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','person']),
   LDAP.mod(LDAP::LDAP_MOD_ADD, 'cn', ['Zara Ali']),
   LDAP.mod(LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES, 'sn', 
                     ['ttate','ALI', "zero\000zero"]),
]

begin
   conn.add("dc = localhost, dc = localdomain", entry1)
   conn.add("cn = Zara Ali, dc = localhost, dc =  localdomain", entry2)
rescue LDAP::ResultError
   conn.perror("add")
   exit
end
conn.perror("add")
conn.unbind

修改 LDAP 条目

修改条目类似于添加条目。 只需使用要修改的属性调用 modify 方法而不是 add。 这是 modify 方法的简单语法。

conn.modify(dn, mods)

此方法使用 DN,dn 和属性,mods 修改条目。 这里,mods 应该是 LDAP::Mod 对象的数组或属性/值数组对的散列。

示例

要修改我们在上一节中添加的条目的姓氏,我们将编写 −

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
entry1 = [
   LDAP.mod(LDAP::LDAP_MOD_REPLACE, 'sn', ['Mohtashim']),
]

begin
   conn.modify("cn = Zara Ali, dc = localhost, dc = localdomain", entry1)
rescue LDAP::ResultError
   conn.perror("modify")
   exit
end
conn.perror("modify")
conn.unbind

删除 LDAP 条目

要删除一个条目,调用 delete 方法,并将可分辨名称作为参数。 这是 delete 方法的简单语法。

conn.delete(dn)

此方法删除一个 DN 为 dn 的条目。

示例

要删除我们在上一节中添加的 Zara Mohtashim 条目,我们将编写 −

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
   conn.delete("cn = Zara-Mohtashim, dc = localhost, dc = localdomain")
rescue LDAP::ResultError
   conn.perror("delete")
   exit
end
conn.perror("delete")
conn.unbind

修改专有名称

无法使用 modify 方法修改条目的可分辨名称。 相反,请使用 modrdn 方法。 这是 modrdn 方法的简单语法 −

conn.modrdn(dn, new_rdn, delete_old_rdn)

此方法使用 DN 修改条目的 RDN,dn,为其提供新的 RDN,new_rdn。 如果 delete_old_rdntrue,则旧的 RDN 值将从条目中删除。

示例

假设我们有以下条目 −

dn: cn = Zara Ali,dc = localhost,dc = localdomain
cn: Zara Ali
sn: Ali
objectclass: person

然后,我们可以用下面的代码修改它的专有名称 −

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
   conn.modrdn("cn = Zara Ali, dc = localhost, dc = localdomain", "cn = Zara Mohtashim", true)
rescue LDAP::ResultError
   conn.perror("modrdn")
   exit
end
conn.perror("modrdn")
conn.unbind

执行搜索

要对 LDAP 目录执行搜索,请将 search 方法与三种不同搜索模式之一结合使用 −

  • LDAP_SCOPE_BASEM − 仅搜索基节点。

  • LDAP_SCOPE_ONELEVEL − 搜索基节点的所有子节点。

  • LDAP_SCOPE_SUBTREE − 搜索包括基节点在内的整个子树。

示例

H在这里,我们将在条目 dc = localhost, dc = localdomain 的整个子树中搜索 person 对象 −

#/usr/bin/ruby -w

require 'ldap'

$HOST =    'localhost'
$PORT =    LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

base = 'dc = localhost,dc = localdomain'
scope = LDAP::LDAP_SCOPE_SUBTREE
filter = '(objectclass = person)'
attrs = ['sn', 'cn']

conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
   conn.search(base, scope, filter, attrs) { |entry|
      # print distinguished name
      p entry.dn
      # print all attribute names
      p entry.attrs
      # print values of attribute 'sn'
      p entry.vals('sn')
      # print entry as Hash
      p entry.to_hash
   }
rescue LDAP::ResultError
   conn.perror("search")
   exit
end
conn.perror("search")
conn.unbind

这将为每个匹配条目调用给定的代码块,其中 LDAP 条目由 LDAP::Entry 类的实例表示。 使用搜索的最后一个参数,您可以指定您感兴趣的属性,省略所有其他属性。 如果您在此处传递 nil,则所有属性都将返回与关系数据库中的"SELECT *"相同。

LDAP::Entry 类的 dn 方法(get_dn 的别名)返回条目的专有名称,使用 to_hash 方法,您可以获得其属性(包括专有名称)的哈希表示。 要获取条目属性的列表,请使用 attrs 方法(get_attributes 的别名)。 此外,要获取一个特定属性值的列表,请使用 vals 方法(get_values 的别名)。


处理错误

Ruby/LDAP 定义了两个不同的异常类 −

  • 如果出现错误,新的、绑定或取消绑定方法会引发 LDAP::Error 异常。

  • 如果添加、修改、删除或搜索 LDAP 目录,则会引发 LDAP::ResultError。


进一步阅读

有关 LDAP 方法的完整详细信息,请参阅 LDAP Documentation 的标准文档。