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

Ldaprecord Laravel Laravel Package

directorytree/ldaprecord-laravel

Integrate LDAP authentication and directory access into Laravel with LdapRecord. Provides user sync, login, Eloquent-style models for LDAP entries, configuration for multiple connections, and utilities for Active Directory and OpenLDAP environments.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require directorytree/ldaprecord-laravel

Publish the config:

php artisan vendor:publish --provider="DirectoryTree\LdapRecordLaravel\LdapRecordLaravelServiceProvider" --tag="config"
  1. Configure LDAP Connection: Edit config/ldaprecord.php with your LDAP server details (host, base DN, bind DN, etc.).

  2. Define an LDAP Model: Extend DirectoryTree\LdapRecordLaravel\Eloquent\LdapModel:

    use DirectoryTree\LdapRecordLaravel\Eloquent\LdapModel;
    
    class User extends LdapModel
    {
        protected $ldapClass = 'user'; // LDAP object class
        protected $ldapAttributes = ['uid', 'mail', 'givenName', 'sn'];
        protected $ldapConnection = 'ldap'; // Config key
    }
    
  3. First Use Case: Authentication Configure auth in config/auth.php:

    'providers' => [
        'ldap' => [
            'driver' => 'ldap',
            'model' => User::class,
        ],
    ],
    

    Use in LoginController:

    use DirectoryTree\LdapRecordLaravel\Auth\LdapAuthenticatable;
    
    public function login(Request $request)
    {
        $credentials = $request->only(['username', 'password']);
        if (Auth::attempt($credentials, $request->filled('remember'))) {
            return redirect()->intended('dashboard');
        }
        return back()->withErrors(['credentials' => 'Invalid credentials']);
    }
    

Implementation Patterns

1. Model Synchronization

Sync with LDAP:

// Sync a single user
$user = User::find(1);
$user->sync();

// Sync all users (with scopes)
User::syncAll(['--scopes' => 'active,verified']);

Import from LDAP:

php artisan ldap:import User --scopes=active,verified

Or programmatically:

User::import(['--scopes' => 'active,verified']);

2. Querying LDAP

Basic Query:

// Find users by attribute
$users = User::where('mail', 'like', '%@example.com')->get();

// Virtual attributes (e.g., memberOf)
$users = User::with('memberOf')->get();

Directory Emulator (for testing):

// Enable emulator in config/ldaprecord.php
'emulator' => [
    'enabled' => true,
    'directory' => database_path('ldap_emulator'),
],

3. Authentication Workflows

Custom Auth Logic:

// Extend LdapAuthenticatable for custom rules
class CustomLdapUser extends LdapAuthenticatable
{
    public function validateCredentials($username, $password)
    {
        // Custom validation (e.g., check password expiry)
        if ($this->isPasswordExpired()) {
            return false;
        }
        return parent::validateCredentials($username, $password);
    }
}

Events for Authentication:

// Listen for rule events
Auth::authenticate(function ($request) {
    event(new \DirectoryTree\LdapRecordLaravel\Events\RulePassed($request));
}, function ($request, $exception) {
    event(new \DirectoryTree\LdapRecordLaravel\Events\RuleFailed($request, $exception));
});

4. Attribute Mapping

Dynamic Attribute Handling:

// In User model
protected $ldapAttributeHandlers = [
    'fullName' => function ($value) {
        return $value ? explode(' ', $value)[0] . ' ' . explode(' ', $value)[1] : null;
    },
    'isActive' => function ($value) {
        return $value === 'TRUE';
    },
];

Invokable Handlers (v3.0.5+):

protected $ldapAttributeHandlers = [
    'formattedName' => \App\Handlers\FormatName::class,
];

5. Browsing LDAP

CLI Tool:

php artisan ldap:browse --connection=ldap --base-dn="ou=users,dc=example,dc=com" --attributes="uid,mail"

Programmatic Browse:

$entries = \DirectoryTree\LdapRecordLaravel\Facades\LdapRecord::list('ou=users,dc=example,dc=com', ['uid', 'mail']);

Gotchas and Tips

Common Pitfalls

  1. Password Hashing:

    • If password_column is set to false, do not rehash passwords (fixed in v3.3.2).
    • Ensure rehashPasswordIfRequired is implemented in custom auth providers (v3.3.1).
  2. Directory Emulator Quirks:

    • Base DN Substitution: Ensure compatibility with recent LdapRecord updates (v3.1.2).
    • Missing Return Values: Some query methods may not return values in emulator mode (v3.0.6).
    • Detaching Relations: Use detach() explicitly for memberof or other relations (v3.0.8).
  3. Logging:

    • Logging level is configurable via logging.level (v3.1.0), but wildcard listeners are only registered if logging is enabled (v3.3.4).
    • Use LogManager::channel() for custom logging channels (v3.2.2).
  4. Scopes in Imports:

    • Scopes in LdapImporter must be comma-separated (v2.7.0).
    • --delete-missing uses Eloquent’s deleted_at format (v3.4.1).
  5. UTF-8 Encoding:

    • Avoid utf8_encode; use mb_convert_encoding (v3.2.1).
  6. Laravel Version Gaps:

    • Laravel 13: Requires v3.4.3+.
    • Laravel 12/11/10: Use v3.4.0+, v3.3.0+, or v2.7.2+ respectively.

Debugging Tips

  1. Enable LDAP Logging:

    'logging' => [
        'enabled' => true,
        'level' => 'debug', // 'info', 'debug', 'error'
        'channel' => 'single', // or custom channel name
    ],
    

    View logs via php artisan ldap:browse --verbose.

  2. Directory Emulator Debugging:

    • Dump emulator data:
      \DirectoryTree\LdapRecordLaravel\Facades\LdapRecord::emulator()->dump();
      
    • Reset emulator:
      php artisan ldap:emulator:reset
      
  3. Authentication Debugging:

    • Check RulePassed/RuleFailed events for failed logins.
    • Use causedByInvalidCredentials() in LoginController (fixed in v3.1.1):
      if (Auth::attempt($credentials) === false) {
          if (Auth::causedByInvalidCredentials()) {
              // Handle invalid credentials
          }
      }
      

Extension Points

  1. Custom Attribute Handlers:

    • Use closures or invokable classes for dynamic transformations (v3.0.5).
  2. Override Sync Logic:

    // In User model
    public function sync()
    {
        // Custom sync logic before/after parent sync
        $this->beforeSync();
        parent::sync();
        $this->afterSync();
    }
    
  3. Extend LdapAuthenticatable:

    • Override validateCredentials() or retrieveByCredentials() for custom auth logic.
  4. Custom LDAP Connections:

    • Define multiple connections in config/ldaprecord.php and use them in models:
      protected $ldapConnection = 'ldap_backup';
      
  5. Event Listeners:

    • Listen for LdapRecord\Events\* or package-specific events (e.g., RulePassed).

Performance Tips

  1. Batch Imports:

    • Use --chunk in ldap:import to avoid memory issues:
      php artisan ldap:import User --chunk=100
      
  2. Selective Attribute Loading:

    • Limit attributes in queries to reduce LDAP traffic:
      User::select(['uid', 'mail'])->get();
      
  3. Caching:

    • Cache frequent LDAP queries using Laravel’s cache:
      $users = Cache::remember('ldap_users_active', now()->addHours(1), function () {
          return User::where('isActive', true
      
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