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: a PHP LDAP client built on top of the PHP ldap extension. Stable since Symfony 3.1, offering tools to connect, bind, search, and manage directory entries. Docs, issues, and PRs are handled in the main Symfony repo.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package via Composer:
    composer require symfony/ldap
    
  2. Enable the PHP LDAP extension in your php.ini:
    extension=ldap
    
  3. Basic connection in Laravel (e.g., in a service provider):
    use Symfony\Component\Ldap\LdapClient;
    
    $client = new LdapClient('ext_ldap', [
        'host' => 'ldap.example.com',
        'port' => 389,
        'encryption' => 'ssl',
        'options' => [
            LDAP_OPT_PROTOCOL_VERSION => 3,
            LDAP_OPT_REFERRALS => 0,
        ],
    ]);
    

First Use Case: User Authentication

use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Query;

// Bind to LDAP with user credentials
$client->bind('uid=user1,dc=example,dc=com', 'password');

// Search for a user
$query = new Query();
$query->where('uid')->equals('user1');

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

if ($entry) {
    $dn = $entry->getDn(); // e.g., "uid=user1,ou=users,dc=example,dc=com"
    $attributes = $entry->getAttribute('mail'); // ['user1@example.com']
}

Implementation Patterns

Core Workflows

1. Connection Management

  • Reusable connections: Use Laravel’s service container to bind the LdapClient:
    // In AppServiceProvider::boot()
    $this->app->singleton(LdapClient::class, function () {
        return new LdapClient('ext_ldap', [
            'host' => config('ldap.host'),
            'port' => config('ldap.port'),
            'encryption' => config('ldap.encryption'),
        ]);
    });
    
  • Resettable adapters: Reset the connection if it fails:
    try {
        $client->bind(...);
    } catch (\Exception $e) {
        $client->reset();
        $client->bind(...);
    }
    

2. Searching and Querying

  • Complex queries with Query builder:
    $query = new Query();
    $query
        ->where('objectClass')->equals('person')
        ->andWhere('mail')->like('%@example.com')
        ->orderBy('sn', 'ASC')
        ->limit(10);
    
  • Paging for large result sets:
    $results = $client->search('ou=users,dc=example,dc=com', $query, ['attributes' => ['cn', 'mail']]);
    $results->count(); // Total entries (may exceed limit)
    $results->all();  // Load all entries (use cautiously)
    

3. User Provisioning

  • Create/update entries:
    $entry = Entry::fromDn('uid=newuser,ou=users,dc=example,dc=com');
    $entry->setAttribute('objectClass', ['top', 'person', 'inetOrgPerson']);
    $entry->setAttribute('cn', 'New User');
    $entry->setAttribute('sn', 'User');
    $entry->setAttribute('uid', 'newuser');
    $entry->setAttribute('mail', 'newuser@example.com');
    $entry->setAttribute('userPassword', 'password');
    
    $client->update($entry);
    
  • Bulk operations with EntryManager:
    $manager = new EntryManager($client);
    $manager->update($entry, ['preserveExistingAttributes' => true]);
    

4. Group Management

  • Check group membership:
    $query = new Query();
    $query->where('member')->equals($userEntry->getDn());
    
    $results = $client->search('ou=groups,dc=example,dc=com', $query);
    $isAdmin = $results->count() > 0;
    

5. SASL Bind (for AD)

  • Bind with SASL mechanism (e.g., GSSAPI for Kerberos):
    $client->bind('uid=user1,dc=example,dc=com', null, [
        'mechanism' => 'GSSAPI',
        'auth' => 'user1@example.com',
    ]);
    

Integration with Laravel

Authentication

  • Custom Laravel Auth Provider:
    use Illuminate\Contracts\Auth\Authenticatable;
    use Symfony\Component\Ldap\Entry;
    
    class LdapUser implements Authenticatable {
        protected $entry;
    
        public function __construct(Entry $entry) {
            $this->entry = $entry;
        }
    
        public function getAuthIdentifier() {
            return $this->entry->getDn();
        }
    
        public function getAuthPassword() {
            return $this->entry->getAttribute('userPassword')[0] ?? '';
        }
    
        public function getRoles() {
            return $this->entry->getAttribute('memberOf') ?? [];
        }
    }
    

Caching

  • Cache LDAP results to reduce server load:
    use Illuminate\Support\Facades\Cache;
    
    $cacheKey = 'ldap_users_' . md5($query->getWhere());
    $results = Cache::remember($cacheKey, now()->addHours(1), function () use ($client, $query) {
        return $client->search('dc=example,dc=com', $query);
    });
    

Configuration

  • Centralize LDAP settings in config/ldap.php:
    return [
        'host' => env('LDAP_HOST', 'ldap.example.com'),
        'port' => env('LDAP_PORT', 389),
        'encryption' => env('LDAP_ENCRYPTION', 'ssl'),
        'base_dn' => 'dc=example,dc=com',
        'user_dn_pattern' => 'uid=%s,' . env('LDAP_USER_BASE_DN', 'ou=users,dc=example,dc=com'),
        'group_dn_pattern' => 'cn=%s,' . env('LDAP_GROUP_BASE_DN', 'ou=groups,dc=example,dc=com'),
    ];
    

Gotchas and Tips

Common Pitfalls

  1. Connection Timeouts

    • Issue: Default socket timeout may be too short for slow LDAP servers.
    • Fix: Configure in the adapter options:
      'options' => [
          LDAP_OPT_TIMEOUT => 10, // 10 seconds
      ]
      
  2. Case Sensitivity in DN

    • Issue: LDAP DNs are case-insensitive, but PHP’s ldap extension may not handle this consistently.
    • Fix: Normalize DNs before use:
      $dn = strtolower($entry->getDn());
      
  3. Attribute Name Variations

    • Issue: Different LDAP servers use different attribute names (e.g., uid vs. sAMAccountName for AD).
    • Fix: Use a config file to map attributes per environment:
      'attribute_mappings' => [
          'username' => env('LDAP_USERNAME_ATTR', 'uid'),
          'email' => env('LDAP_EMAIL_ATTR', 'mail'),
      ]
      
  4. Referrals

    • Issue: LDAP servers may return referrals, causing infinite loops.
    • Fix: Disable referrals in the adapter:
      'options' => [
          LDAP_OPT_REFERRALS => 0,
      ]
      
  5. Memory Leaks with Large Results

    • Issue: Loading all entries from a large directory can exhaust memory.
    • Fix: Use pagination or limit results:
      $query->limit(100);
      $results = $client->search(..., $query);
      
  6. SASL Bind Failures

    • Issue: SASL binds (e.g., GSSAPI) may fail due to misconfigured Kerberos.
    • Fix: Test with simple binds first, then enable SASL:
      // Test simple bind
      $client->bind('uid=user1,dc=example,dc=com', 'password');
      
      // Then enable SASL
      $client->bind('uid=user1,dc=example,dc=com', null, [
          'mechanism' => 'GSSAPI',
      ]);
      

Debugging Tips

  1. Enable LDAP Debugging

    • Set the LDAP_OPT_DEBUG_LEVEL option to log operations:
      'options' => [
          LDAP_OPT_DEBUG_LEVEL => 7,
      ]
      
    • Check PHP error logs for LDAP debug output.
  2. **Validate LDAP Filters

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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours