Ruby Ruby/LDAP 教程
Ruby 与 Net::LDAP 库操作 LDAP
Section titled “Ruby 与 Net::LDAP 库操作 LDAP”LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是一种用于访问和维护分布式目录信息服务的协议。Ruby 可以使用 net-ldap 这个 gem(Ruby 包/库)与 LDAP 服务器交互,net-ldap 是一个纯 Ruby 的 LDAP 客户端库。
net-ldap gem 支持常见的 LDAP 操作,如连接、绑定、搜索、添加、修改和删除条目。它旨在与 LDAP 相关的 RFC(请求评论)文档兼容。
net-ldap 安装:
Section titled “net-ldap 安装:”在使用 net-ldap 之前,您需要安装它。通常使用 RubyGems 完成:
$ gem install net-ldap请确保您有一个正在运行的 LDAP 服务器(例如 OpenLDAP、Active Directory 或基于云的 LDAP 服务)用于测试示例。示例将假定使用本地 OpenLDAP 服务器,但连接详细信息可以轻松调整。
建立 LDAP 连接:
Section titled “建立 LDAP 连接:”连接到 LDAP 服务器涉及创建一个 Net::LDAP 对象,然后绑定到目录。
步骤 1:创建连接对象
Section titled “步骤 1:创建连接对象”您可以使用服务器详细信息初始化一个 Net::LDAP 对象:
require 'net/ldap'
ldap = Net::LDAP.new host: '127.0.0.1', # Your LDAP server IP or hostname port: 389, # Standard LDAP port (636 for LDAPS) auth: { method: :simple, username: "cn=admin,dc=example,dc=com", # Your admin DN password: "password" # Your admin password }host:LDAP 服务器的主机名或 IP 地址。port:LDAP 服务的端口号(默认是 389,或用于 LDAPS/SSL 的 636)。auth:一个哈希,指定认证方法和凭据。:simple是常见的一种。
这会创建一个对象,但不会立即连接或绑定。
步骤 2:绑定
Section titled “步骤 2:绑定”绑定用于认证您的会话。如果在初始化期间提供了认证详细信息,net-ldap 在尝试操作时通常会执行隐式绑定。您也可以使用 ldap.bind 显式绑定。
if ldap.bind # Successfully bound to LDAP server puts "Authentication successful!" # ... perform operations ...else # Bind failed puts "Authentication failed!" puts "LDAP Error Code: #{ldap.get_operation_result.code}" puts "LDAP Error Message: #{ldap.get_operation_result.message}"end检查 ldap.bind 或任何其他操作的结果是一个好习惯。ldap.get_operation_result 提供有关上次操作的详细信息。
示例:基本连接与绑定
Section titled “示例:基本连接与绑定”#!/usr/bin/env rubyrequire 'net/ldap'
ldap_config = { host: 'localhost', # Or your LDAP server IP/hostname port: 389, auth: { method: :simple, username: 'cn=admin,dc=example,dc=com', # Replace with your bind DN password: 'admin_password' # Replace with your password }}
ldap = Net::LDAP.new(ldap_config)
if ldap.bind puts "Successfully connected and bound to the LDAP server." # Operations like search, add, modify, delete would go here.else puts "Connection or bind failed." puts "Error code: #{ldap.get_operation_result.code}" puts "Error message: #{ldap.get_operation_result.message}"end添加 LDAP 条目:
Section titled “添加 LDAP 条目:”要添加条目,需要指定其辨别名(DN,Distinguished Name)和属性(attributes)。
dn = "uid=user1,ou=users,dc=example,dc=com"attributes = { objectclass: ["top", "person", "inetOrgPerson"], cn: "User One", sn: "One", givenName: "User", uid: "user1", mail: "user1@example.com", userPassword: "new_password"}
if ldap.add(dn: dn, attributes: attributes) puts "Entry '#{dn}' added successfully."else puts "Failed to add entry '#{dn}'." puts "Error: #{ldap.get_operation_result.message}"end确保 objectclass 属性对于您的 LDAP 模式和您正在创建的条目类型是正确的。
修改 LDAP 条目:
Section titled “修改 LDAP 条目:”要修改条目,请指定 DN 和一个操作数组(添加、删除、替换属性值)。
dn_to_modify = "uid=user1,ou=users,dc=example,dc=com"operations = [ [:replace, :mail, "user.one@example.com"], # Replace existing mail [:add, :telephoneNumber, "+1234567890"] # Add new attribute]
if ldap.modify(dn: dn_to_modify, operations: operations) puts "Entry '#{dn_to_modify}' modified successfully."else puts "Failed to modify entry '#{dn_to_modify}'." puts "Error: #{ldap.get_operation_result.message}"end删除 LDAP 条目:
Section titled “删除 LDAP 条目:”要删除条目,请提供其 DN。
dn_to_delete = "uid=user1,ou=users,dc=example,dc=com"
if ldap.delete(dn: dn_to_delete) puts "Entry '#{dn_to_delete}' deleted successfully."else puts "Failed to delete entry '#{dn_to_delete}'." puts "Error: #{ldap.get_operation_result.message}"end修改辨别名(RDN):
Section titled “修改辨别名(RDN):”修改条目的相对辨别名(RDN,Relative Distinguished Name)是使用 ldap.rename 完成的。此操作可能不受所有 LDAP 服务器支持,或者可能有限制。
old_dn = "uid=user1,ou=users,dc=example,dc=com"new_rdn = "uid=newuser1"# Optional: new_superior_dn = "ou=new_users,dc=example,dc=com"# delete_old_rdn defaults to true
if ldap.rename(olddn: old_dn, newrdn: new_rdn, delete_attributes: true) # The new DN will be uid=newuser1,ou=users,dc=example,dc=com puts "Entry RDN modified successfully."else puts "Failed to modify RDN." puts "Error: #{ldap.get_operation_result.message}"end搜索需要一个基本 DN(base DN)、作用域(scope)、过滤器(filter),以及可选的要检索的属性。
base_dn = "ou=users,dc=example,dc=com"filter = Net::LDAP::Filter.eq("objectclass", "person") # Find all persons# More complex filter: Net::LDAP::Filter.pres("mail") & Net::LDAP::Filter.eq("sn", "Doe")
attributes_to_fetch = ["cn", "sn", "mail", "uid"]
ldap.search(base: base_dn, filter: filter, attributes: attributes_to_fetch, return_result: false) do |entry| puts "DN: #{entry.dn}" entry.each do |attribute, values| puts " #{attribute}: #{values.join(', ')}" endend
# Check for search errors after the block or if return_result: trueresult = ldap.get_operation_resultif result.code != 0 puts "Search failed: #{result.message}"endbase:开始搜索的 DN。filter:LDAP 过滤器字符串或Net::LDAP::Filter对象。例如,"(uid=user1)"或Net::LDAP::Filter.eq("uid", "user1")。attributes:要返回的属性名称数组。如果为空或 nil,通常返回所有用户属性。scope:可以是Net::LDAP::SearchScope_BaseObject(基对象)、Net::LDAP::SearchScope_SingleLevel(单层)或Net::LDAP::SearchScope_WholeSubtree(整个子树,默认)。return_result: false(块的默认值)在块中处理条目。如果为true,ldap.search将返回一个条目数组。
net-ldap 方法通常在成功时返回 true,在失败时返回 false/nil。操作后,ldap.get_operation_result 提供一个 Net::LDAP::Result 对象,其中包含操作的代码、消息和匹配的 DN。
一个常见的错误检查模式:
if ldap.some_operation(...) # Successelse op_result = ldap.get_operation_result puts "Operation failed!" puts "Code: #{op_result.code}" puts "Message: #{op_result.message}" # op_result.error_message and op_result.matched_dn might also be usefulend对于一些关键问题,可能会抛出 Net::LDAP::Error 异常,因此也可以使用 begin...rescue Net::LDAP::Error => e 进行更广泛的错误处理。
有关 net-ldap 及其功能的全面详细信息,请参阅:
net-ldapGitHub 仓库和文档:https://github.com/ruby-ldap/net-ldap- 官方 LDAP RFC 文档获取协议详细信息。