Net::LDAP Documentation
repository·master·Indexed 19 days ago
https://github.com/ruby-ldap/ruby-net-ldapA pure Ruby client implementation for the Lightweight Directory Access Protocol (LDAP), used to access distributed directory services like OpenLDAP and Active Directory. It provides tools for LDAP searching, binding, and authentication, including support for SASL and GSS-SPNEGO. The library includes utilities for handling LDAP entries and converting data to and from the LDAP Data Interchange Format (LDIF) via Net::LDAP::Dataset.
What's inside Net::LDAP
- Net::LDAP (net-ldap) is a pure Ruby implementation of a client for the Lightweight Directory Access Protocol (LDAP). It is designed to access distributed directory services and has been tested against popular servers like OpenLDAP and Active Directory. It is compliant with several IETF LDAP RFCs (including 2251–2256, 2829–2830, 3377, and 3771).
Understand the Net::LDAP::Dataset abstraction
masterA
Net::LDAP::Datasetacts as an intermediate format for converting LDAP data betweenNet::LDAP::Entryobjects and LDIF strings.It inherits from
Hash, where:- Keys: Represent the Distinguished Name (DN) of an LDAP entry.
- Values: Are hashes where keys are attribute names (symbols) and values are arrays of attribute values.
It supports metadata such as
versionandcommentswhich are preserved during LDIF export.Implement a custom authentication adapter
masterTo support custom authentication methods in
Net::LDAP, you must create a class that inherits fromNet::LDAP::AuthAdapterand implements thebindmethod. Once implemented, you must register your adapter usingNet::LDAP::AuthAdapter.registerto make it available for use by name.class MyCustomAdapter < Net::LDAP::AuthAdapter def bind # Implement custom binding logic using @connection end end # Register the adapter Net::LDAP::AuthAdapter.register(:my_method, MyCustomAdapter)Install Net::LDAP
masterNet::LDAP is a pure Ruby library with no external dependencies. You can install it via RubyGems using the following command:
gem install net-ldapUse GSS-SPNEGO authentication with Net::LDAP
masterGSS-SPNEGO authentication is a provisional method used to perform GSS-SPNEGO authentication with a server (typically Microsoft Active Directory).
Warning: This implementation is PROVISIONAL and intended only for testing SASL implementations. It is not recommended for production use.
To use this method, call
#bindon yourNet::LDAPinstance with the:methodparameter set to:gss_spnego. This method requires both:username(or:dn) and:passwordattributes, similar to the:simpleauthentication method.ldap = Net::LDAP.new( host: 'your-ad-server.com', port: 389 ) ldap.bind( method: :gss_spnego, username: 'user@DOMAIN.COM', password: 'your_password' )Configure the integration test environment via Docker Compose
masterThe project uses Docker Compose to orchestrate an integration testing environment consisting of an OpenLDAP server and multiple Ruby runtime containers (Standard Ruby, TruffleRuby, and JRuby).
OpenLDAP Service
The
openldapservice uses theosixia/openldap:1.4.0image. Key configurations include:- Network Aliases: The service is accessible via
ldap.example.organdcert.mismatch.example.org. - Environment Variables:
LDAP_TLS_VERIFY_CLIENT: Set totry.LDAP_SEED_INTERNAL_LDIF_PATH: Set to/ldifto load initial data.
- Volumes: Mounts
./test/fixtures/ldifto/ldif(read-only) to seed the LDAP directory.
CI Runtime Services
Multiple services (e.g.,
ci-3.0throughci-3.4,ci-truffleruby,ci-jruby-9.3,ci-jruby-9.4) run the integration tests using/code/ci-run.sh. These services rely on the following environment variables to connect to the LDAP server:INTEGRATION: Set toopenldap.INTEGRATION_HOST: Set toldap.example.org.
All CI services depend on the
openldapservice being healthy before starting.services: openldap: image: osixia/openldap:1.4.0 environment: LDAP_TLS_VERIFY_CLIENT: "try" LDAP_SEED_INTERNAL_LDIF_PATH: "/ldif" volumes: - ./test/fixtures/ldif:/ldif:ro ci-3.4: image: ruby:3.4 environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org depends_on: - openldap- Network Aliases: The service is accessible via
Require Net::LDAP in your Ruby project
masterTo use the library in your application, require either
net-ldapornet/ldap.require 'net-ldap' # or require 'net/ldap'Handle Net::LDAP connection and protocol errors
masterWhen working with
Net::LDAP, you should rescueNet::LDAP::Errorto catch most library-specific issues. For connection-specific failures, the library provides specialized error classes.Key error classes include:
Net::LDAP::ConnectionError: Raised when the client is unable to connect to any of the provided servers. It provides a detailed message listing the specific errors encountered for each host and port.Net::LDAP::SocketError: Related to underlying socket issues.Net::LDAP::AlreadyOpenedError: Raised if an attempt is made to open a connection that is already open.Net::LDAP::StartTLSError: Raised when a StartTLS operation fails.Net::LDAP::NoOpenSSLError: Raised if OpenSSL is not available.
For protocol and LDAP-specific logic errors, use these classes:
Net::LDAP::InvalidDNError/Net::LDAP::EmptyDNError: Issues with Distinguished Names.Net::LDAP::SearchFilterError/Net::LDAP::FilterSyntaxInvalidError: Issues with LDAP search filters.Net::LDAP::AuthMethodUnsupportedError/Net::LDAP::BindingInformationInvalidError: Issues with authentication or binding.Net::LDAP::EncryptionUnsupportedError/Net::LDAP::EncMethodUnsupportedError: Issues with encryption settings.
Register custom authentication adapters
masterUse
Net::LDAP::AuthAdapter.register(names, adapter)to map one or more authentication method names to a specific adapter class.names: A single symbol/string or an array of symbols/strings representing the authentication methods.adapter: The class that implements the authentication logic.
Net::LDAP::AuthAdapter.register([:method_one, :method_two], MyAdapterClass)Retrieve a registered authentication adapter
masterYou can retrieve a registered adapter by its name using the bracket syntax:
Net::LDAP::AuthAdapter[name].If the requested
namehas not been registered, it will raise aNet::LDAP::AuthMethodUnsupportedErrorwith the message"Unsupported auth method (#{name})".adapter = Net::LDAP::AuthAdapter[:my_method]Configure SASL authentication with Net::LDAP
masterWhen performing a SASL bind, you must provide an authentication hash containing three specific keys:
:mechanism,:initial_credential, and:challenge_response.:mechanism: A string representing the SASL mechanism (e.g., 'DIGEST-MD5').:initial_credential: The initial credential (usually a string) sent in the firstBindRequest.:challenge_response: A RubyProcused to handle multi-step authentication. This block is triggered when the server returns a result code of14(saslBindInProgress). The proc receives the server's credentials (from thesaslServerCredsfield) as an argument and must return the next credential string to be sent to the server. The proc may be called multiple times until authentication is complete.
Note: The authentication process is limited to a maximum of 10 challenges to prevent infinite loops; exceeding this will raise a
Net::LDAP::SASLChallengeOverflowError.# Example of a SASL authentication hash auth_params = { mechanism: 'DIGEST-MD5', initial_credential: 'initial_password', challenge_response: ->(server_creds) { # server_creds contains the data from saslServerCreds # Return the next response string required by the server "next_response_string" } } # Usage with a Net::LDAP connection ldap.bind(auth_params)Read and write attributes in Net::LDAP::Entry
masterYou can manipulate attributes within an
Net::LDAP::Entryusing bracket notation. The library handles canonicalization (lowercasing and symbol conversion) internally.- Reading:
entry[:name]orentry['name']returns anArrayof values. To get just the first value, useentry.first(:name). - Writing:
entry[:name] = valuesets or replaces the attribute values. The value is automatically converted into an array.
Example of manual instantiation and manipulation:
entry = Net::LDAP::Entry.new("dc=com") entry["foo"] = 12345 # Sets attribute 'foo' to [12345] puts entry.foo # => [12345]entry = Net::LDAP::Entry.new("dc=com") entry.foo # => NoMethodError entry["foo"] = 12345 # => [12345] entry.foo # => [12345]- Reading: