Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ldap Laravel Package

symfony/ldap

Symfony LDAP component: an LDAP client for PHP built on the PHP ldap extension. Provides tools to connect, bind, search, and manage LDAP directories. Stable since Symfony 3.1; earlier versions were internal and may break when upgrading.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require symfony/ldap
    

    Ensure PHP’s ldap extension is enabled in php.ini.

  2. Configure the connection (Laravel service provider):

    use Symfony\Component\Ldap\LdapClient;
    use Symfony\Component\Ldap\Adapter\ExtLdapAdapter;
    
    $adapter = new ExtLdapAdapter('ldap://your-server:389');
    $client = new LdapClient($adapter);
    
  3. First use case: Bind and search

    $client->bind('cn=admin,dc=example,dc=com', 'password');
    $results = $client->search('ou=users,dc=example,dc=com', '(uid=jdoe)');
    foreach ($results as $entry) {
        echo $entry->getDn() . "\n";
    }
    

Where to Look First

  • Symfony LDAP Documentation (official API reference).
  • ExtLdapAdapter (for connection management) and LdapClient (core operations).
  • LdapQuery (for building complex searches) and LdapEntry (for handling results).

Implementation Patterns

Core Workflows

1. Authentication (LDAP Bind)

$adapter = new ExtLdapAdapter('ldap://ad.example.com');
$client = new LdapClient($adapter);

try {
    $client->bind('uid=jdoe,ou=users', 'password');
    // Authenticated—proceed with operations.
} catch (\Symfony\Component\Ldap\Exception\ConnectionException $e) {
    // Handle failed bind (e.g., invalid credentials).
}

2. Searching with Filters

$query = new LdapQuery();
$query
    ->where('objectClass', 'person')
    ->where('mail', '=john@example.com')
    ->limit(10);

$results = $client->search('ou=users,dc=example,dc=com', $query);

3. Modifying Entries

$entry = $client->findEntry('uid=jdoe,ou=users');
$entry->setAttribute('mail', 'john.doe@example.com');
$client->update($entry);

4. Group-Based Role Assignment (Laravel Integration)

// In Laravel’s AuthServiceProvider:
public function boot()
{
    $this->app['auth']->provider('ldap', function ($app) {
        $adapter = new ExtLdapAdapter('ldap://ad.example.com');
        $client = new LdapClient($adapter);

        return new SymfonyLdapUserProvider($client, 'ou=users');
    });
}

5. Bulk Operations (User Provisioning)

$users = $client->search('ou=users', '(objectClass=person)');
foreach ($users as $user) {
    $user->setAttribute('employeeNumber', '12345');
    $client->update($user);
}

Integration Tips

Laravel-Specific Patterns

  • Service Container Binding:

    $this->app->singleton(LdapClient::class, function ($app) {
        $adapter = new ExtLdapAdapter(config('ldap.server'));
        return new LdapClient($adapter);
    });
    
  • Configurable LDAP Servers:

    // config/ldap.php
    return [
        'servers' => [
            'primary' => [
                'host' => 'ldap.example.com',
                'port' => 389,
                'encryption' => 'tls',
            ],
        ],
    ];
    
  • Queue Jobs with Resettable Adapter:

    // In a Laravel queue job:
    public function handle()
    {
        $adapter = new ExtLdapAdapter('ldap://ad.example.com');
        $client = new LdapClient($adapter);
    
        try {
            $client->bind('...');
            // Perform operations.
        } finally {
            $adapter->reset(); // Critical for long-running jobs!
        }
    }
    

Symfony Security Bundle

  • Use form_login_ldap for authentication:
    # config/packages/security.yaml
    firewalls:
        main:
            form_login_ldap:
                check_path: /login_check
                provider: ldap
    

Gotchas and Tips

Pitfalls

  1. Connection Leaks in Queues/Jobs

    • Issue: Forgetting to call $adapter->reset() in long-running processes (e.g., Laravel queues) can exhaust LDAP server connections.
    • Fix: Always wrap LDAP operations in try/finally blocks to reset the adapter:
      try {
          $client->bind(...);
          // Operations...
      } finally {
          $adapter->reset();
      }
      
  2. Case Sensitivity in Filters

    • Issue: LDAP filters are case-insensitive by default, but some attributes (e.g., uid) may behave unexpectedly.
    • Fix: Use exact matches or normalize case:
      $query->where('uid', '=JohnDoe'); // May fail if 'uid' is stored as 'johndoe'.
      
  3. Schema Mismatches

    • Issue: Assuming all LDAP servers use the same schema (e.g., objectClass=person vs. objectClass=user).
    • Fix: Inspect the schema with:
      $schema = $client->getSchema('ou=users');
      
  4. TLS/SSL Configuration

    • Issue: Misconfigured TLS can cause connection failures.
    • Fix: Use ExtLdapAdapter with explicit TLS settings:
      $adapter = new ExtLdapAdapter('ldap://ad.example.com:636', [
          'options' => [
              LDAP_OPT_PROTOCOL_VERSION => 3,
              LDAP_OPT_REFERRALS => 0,
          ],
          'encryption' => 'ssl',
      ]);
      
  5. Deprecated Methods

    • Issue: Using eraseCredentials() (deprecated in Symfony 7.3+).
    • Fix: Avoid calling it on LdapUser objects; Symfony’s security component handles credentials securely.

Debugging Tips

  1. Enable LDAP Debugging

    $adapter = new ExtLdapAdapter('ldap://ad.example.com', [
        'options' => [
            LDAP_OPT_DEBUG_LEVEL => 7, // Enable verbose logging
        ],
    ]);
    
  2. Validate DN Formats

    • Use LdapEntry::getDn() to inspect Distinguished Names (DNs). Invalid DNs will cause silent failures.
  3. Test with a Local LDAP Server

    • Use OpenLDAP or 389 Directory Server for local testing:
      docker run -p 389:389 -p 636:636 osixia/openldap
      
  4. Handle Timeouts Gracefully

    • Set a timeout in the adapter options:
      $adapter = new ExtLdapAdapter('ldap://ad.example.com', [
          'options' => [
              LDAP_OPT_NETWORK_TIMEOUT => 5, // 5 seconds
          ],
      ]);
      

Extension Points

  1. Custom Query Builders

    • Extend LdapQuery for domain-specific filters:
      class UserQuery extends LdapQuery
      {
          public function active()
          {
              return $this->where('accountStatus', '=active');
          }
      }
      
  2. Attribute Mappers

    • Transform LDAP attributes to Laravel models:
      $user = new User();
      $user->name = $entry->getAttribute('cn')[0];
      $user->email = $entry->getAttribute('mail')[0];
      
  3. Event Listeners

    • Hook into LDAP operations (e.g., log searches):
      $client->addListener(new class implements LdapEventListenerInterface {
          public function onSearch(LdapEvent $event) {
              logger()->info('LDAP Search:', $event->getQuery());
          }
      });
      
  4. Custom Adapters

    • Implement LdapAdapterInterface for non-ExtLdap backends (e.g., Active Directory-specific logic):
      class AdLdapAdapter implements LdapAdapterInterface
      {
          public function bind($dn, $password) { /* ... */ }
          // Implement other methods...
      }
      

Performance Tips

  1. Batch Operations
    • Use `LDAP_OPT_BIND
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport