Laravel AD LDAP

  • Enable PHP for LDAP via INI by enabling the ldap extension:
extension=ldap
  • Install LDAP Record (installs in vendor\directorytree folder)
composer require directorytree/ldaprecord-laravel
  • Publish the LDAP configuration file
php artisan vendor:publish --provider="LdapRecord\Laravel\LdapServiceProvider"
  • Make sure you re-run config:cache after making config changes, to re-cache your modifications, otherwise your config changes won't take affect!

edit the config/ldap.php host variable

//'hosts' => [env('LDAP_HOST', '127.0.0.1')], // This is the original Entry - comment out and replace with below
'hosts' => [env('LDAP_HOST1', '127.0.0.1'), env('LDAP_HOST2', '127.0.0.1')],
  • Configure your LDAP connection (tls recommended - not setup below - as lab environment)
LDAP_LOGGING=true
LDAP_CONNECTION=default
LDAP_HOST1=LAB2-AD-01.lab2.purplepi.ie
LDAP_HOST2=192.168.1.236
LDAP_USERNAME="CN=ldap user,CN=Users,DC=lab2,DC=purplepi,DC=ie"
LDAP_PASSWORD=PKwpQtJe:A}J8vM=
LDAP_PORT=389
LDAP_BASE_DN="DC=lab2,DC=purplepi,DC=ie"
LDAP_TIMEOUT=5
LDAP_SSL=false
LDAP_TLS=false
  • create a new LdapRecord model
  • Confirm if needed - I think not for authenticaion - but if you want to do lookups on specific AD attributes that are not stored in the database
php artisan make:ldap-model User
  • Edit your config/auth.php file
// config/auth.php
 
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'ldap', // Changed to 'ldap'
    ],
 
 
'providers' => [
    // ...
 
    'ldap' => [
        'driver' => 'ldap',
        'model' => LdapRecord\Models\ActiveDirectory\User::class,
    ],
  • Edit vendor\laravel\ui\auth-backend\AuthenticatesUsers.php
    • Note the Documentation states to edit the LoginController - but if you have installed laravel UI with authentication you would edit the above file.
    protected function credentials(Request $request)
    {
        return [
            'mail' => $request->get('email'),
            'password' => $request->get('password'),
        ];
    }
  • Publish the Migration
    • LdapRecord requires you to have two additional user database columns, guid and domain.
php artisan vendor:publish --provider="LdapRecord\Laravel\LdapAuthServiceProvider"
php artisan migrate
  • Setting up your database user model
    • These are required so LdapRecord can set and retrieve your users domain and guid database columns.
// app/User.php
 
// ...
use LdapRecord\Laravel\Auth\AuthenticatesWithLdap;
use LdapRecord\Laravel\Auth\LdapAuthenticatable;
 
class User extends Authenticatable implements LdapAuthenticatable
{
    use Notifiable, AuthenticatesWithLdap;
 
    // ...
}
  • Use the –delete option to soft delete users who have been disabled
  • Use the –delete-missing option to delete any users not found (because they have been deleted on the AD) - be careful if not found in filter - then all existing users could be soft deleted! (can restore if necessary using a simple SQL query).
  • Use the –restore option to un-softdelete a user if they have been reenabled.
php artisan ldap:import ldap --filter "(objectclass=user)" --delete-missing --delete --restore

Sync any users who are Enabled

php artisan ldap:import ldap --filter "(&(objectclass=user)(|(userAccountControl=512)(userAccountControl=66048)))

Sync any users who are Disabled and who are NOT SystemCriticalObjects

php artisan ldap:import ldap --filter "(&(objectclass=user)(!(isCriticalSystemObject=TRUE))(|(userAccountControl=514)(userAccountControl=66050)))

Note: to use scheduling you must set up a cronjob or task manager to run ever min.

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

For more details click here

Reference
To run the import as a scheduled job, place the following in your app/Console/Kernel.php in the command scheduler:

protected function schedule(Schedule $schedule)
{
    // Import LDAP users hourly.
    $schedule->command('ldap:import ldap', [
        '--no-interaction',
        '--restore',
        '--delete',
        '--filter' => '(objectclass=user)',
    ])->hourly();
}

Lets say you only want to allow users who are a member of IVRadmin to log in. Reference

  • Create an authentication rule
php artisan make:ldap-rule IVRAdmin

Edit this new rule - full example below:

<?php
 
namespace App\Ldap\Rules;
 
use LdapRecord\Laravel\Auth\Rule;
use LdapRecord\Models\ActiveDirectory\Group;
 
class IVRAdmin extends Rule
{
    /**
     * Check if the rule passes validation.
     *
     * @return bool
     */
    public function isValid()
    {
        $ivradmin = Group::find('CN=IVRAdmin,CN=Users,DC=lab2,DC=purplepi,DC=ie');
 
        return $this->user->groups()->recursive()->exists($ivradmin);
    }
}
  • Add the rule to the authentication provider
  1. >
  2. 'providers' => [
  3. // ...
  4.  
  5. 'ldap' => [
  6. 'driver' => 'ldap',
  7. 'model' => LdapRecord\Models\ActiveDirectory\User::class,
  8. 'rules' => [
  9. App\Ldap\Rules\IVRAdmin::class,
  10. ],
  11. 'database' => [
  12. 'model' => App\User::class,
  13. 'sync_passwords' => false,
  14. 'sync_attributes' => [
  15. 'name' => 'cn',
  16. 'email' => 'mail',
  17. ],
  18. ],
  19. ],
  20. ],
  • If you are caching your configuration, make sure you re-run config:cache to re-cache your modifications.

Using the option

 'password_column' => false 

allows you to remove the password column from the users table. Reference: https://ldaprecord.com/docs/laravel/auth/configuration/#database-password-sync

    'providers' => [
 
        'ldap' => [
            'driver' => 'ldap',
            'model' => LdapRecord\Models\ActiveDirectory\User::class,
            'database' => [
                'password_column' => false, 
                'model' => App\User::class,
                'sync_attributes' => [
                    'name' => 'cn',
                    'username' => 'samaccountname',
                ],
            ],
        ],
    ],
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies