Laravel AD LDAP
Reference:
My quick Start Guide
- 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!
Enable Resilient LDAP server setup
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; // ... }
Importing Users
- 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)))
Scheduling the command
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(); }
Restricting Access
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
> 'providers' => [ // ... 'ldap' => [ 'driver' => 'ldap', 'model' => LdapRecord\Models\ActiveDirectory\User::class, 'rules' => [ App\Ldap\Rules\IVRAdmin::class, ], 'database' => [ 'model' => App\User::class, 'sync_passwords' => false, 'sync_attributes' => [ 'name' => 'cn', 'email' => 'mail', ], ], ], ],
- If you are caching your configuration, make sure you re-run config:cache to re-cache your modifications.
Removing the Password column
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', ], ], ], ],