avatarBalaji Dharma

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

6486

Abstract

to one of the Adldap2-Laravel <a href="https://adldap2.github.io/Adldap2-Laravel/#/auth/events">events</a>. This event listener will save or update the user roles based on the LDAP group.</p><h2 id="8e71">Create Event Listener for sync Role</h2><p id="a923">We going to create the listener with the name AdldapSyncRoles by using the <code>make:listener</code> artisan command.</p><div id="ac0e"><pre>./vendor/bin/sail artisan make:listener AdldapSyncRoles</pre></div><p id="1a5b">Open the app/Listeners/AdldapSyncRoles.php file and replace it with the below Role syncing-related changes. We going to listen to the Adldap AuthenticationSuccessful event. This event will trigger after the user is successfully authenticated with LDAP.</p><div id="49e0"><pre><span class="hljs-meta"><?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title class_">App</span><span class="hljs-title class_">Listeners</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span><span class="hljs-title">Models</span><span class="hljs-title">Role</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Adldap</span><span class="hljs-title">Laravel</span><span class="hljs-title">Events</span><span class="hljs-title">AuthenticationSuccessful</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Adldap</span><span class="hljs-title">Laravel</span><span class="hljs-title">Facades</span><span class="hljs-title">Adldap</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AdldapSyncRoles</span> </span>{ <span class="hljs-comment">/** * Handle the event. * * <span class="hljs-doctag">@param</span> AuthenticationSuccessful event * * <span class="hljs-doctag">@return</span> void */</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params">AuthenticationSuccessful <span class="hljs-variable">event</span></span>) </span>{ <span class="hljs-variable">assigned</span> = []; <span class="hljs-variable">user_group</span> = []; <span class="hljs-variable">uid</span> = <span class="hljs-variable">event</span>->user-><span class="hljs-title function_ invoke__">getAttribute</span>(<span class="hljs-string">'uid'</span>)[<span class="hljs-number">0</span>]; <span class="hljs-variable">roles</span> = <span class="hljs-title class_">Role</span>::<span class="hljs-title function_ invoke__">all</span>(); <span class="hljs-variable">groups</span> = <span class="hljs-title class_">Adldap</span>::<span class="hljs-title function_ invoke__">search</span>()-><span class="hljs-title function_ invoke__">where</span>(<span class="hljs-string">'objectClass'</span>, <span class="hljs-string">'posixGroup'</span>)-><span class="hljs-title function_ invoke__">get</span>();

    <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$groups</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$group</span>) {
        <span class="hljs-keyword">if</span>(<span class="hljs-title function_ invoke__">in_array</span>(<span class="hljs-variable">$uid</span>, <span class="hljs-variable">$group</span>-&gt;<span class="hljs-title function_ invoke__">getAttribute</span>(<span class="hljs-string">'memberuid'</span>))) {
            <span class="hljs-variable">$user_group</span>[] = <span class="hljs-variable">$group</span>-&gt;<span class="hljs-title function_ invoke__">getAttribute</span>(<span class="hljs-string">'cn'</span>)[<span class="hljs-number">0</span>];
        }
    }

    <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$roles</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$role</span>) {
        <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">in_array</span>(<span class="hljs-variable">$role</span>-&gt;name, <span class="hljs-variable">$user_group</span>)) {
            <span class="hljs-variable">$assigned</span>[] = <span class="hljs-variable">$role</span>-&gt;id;
        }
    }

    <span class="hljs-variable">$event</span>-&gt;model-&gt;<span class="hljs-title function_ invoke__">syncRoles</span>(<span class="hljs-variable">$assigned</span>);
}

}</pre></div><p id="5c56">We using OpenLDAP, so we cannot use the $event->user->inGroup() method. So we manually fetched the groups and assigned the user group to the new array.</p><p id="6992">If you using any other Active Directory means (for Example Windows) use the below code</p><div id="38e3"><pre><span class="hljs-meta"><?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title class_">App</span><span class="hljs-title class_">Listeners</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span><span class="hljs-title">Users</span><span class="hljs-title">Role</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Adldap</span><span class="hljs-title">Laravel</span><span class="hljs-title">Events</span><span class="hljs-title">AuthenticationSuccessful</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SuccessfulLDAPLoginListener</span> </span>{ <span class="hljs-comment">/** * Handle the event. * * <span class="hljs-doctag">@param</span> AuthenticationSuccessful event * * <span class="hljs-doctag">@return</span> void */</span> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params">AuthenticationSuccessful <span class="hljs-variable">event</span></span>) </span>{ <span class="hljs-variable">assigned</span> = []; <span class="hljs-variable">roles</span> = <span class="hljs-title class_">Role</span>::<span class="hljs-title function_ invoke__">all</span>(); <span class="hljs-keyword">foreach</span> (<span class="hljs-variable">roles</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">role</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-variable">$event</span>->user-><span class="hljs-title functio

Options

n_ invoke__">inGroup</span>(<span class="hljs-variable">role</span>-&gt;name)) { <span class="hljs-variable">assigned</span>[] = <span class="hljs-variable">$role</span>->role_id; } }

    <span class="hljs-variable">$event</span>-&gt;model-&gt;<span class="hljs-title function_ invoke__">syncRoles</span>(<span class="hljs-variable">$assigned</span>);
}

}</pre></div><p id="3a90">Next step we going to check our role synching changes by adding a new user in PHP LDAP admin.</p><h2 id="da88">Registering new Listeners</h2><p id="201b">Open the EventServiceProvider and add register our event and listener</p><p id="9c75"><code>app\Providers\EventServiceProvider.php</code></p><div id="a7b8"><pre><span class="hljs-meta"><?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title class_">App</span><span class="hljs-title class_">Providers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span><span class="hljs-title">Auth</span><span class="hljs-title">Events</span><span class="hljs-title">Registered</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span><span class="hljs-title">Auth</span><span class="hljs-title">Listeners</span><span class="hljs-title">SendEmailVerificationNotification</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Adldap</span><span class="hljs-title">Laravel</span><span class="hljs-title">Events</span><span class="hljs-title">AuthenticationSuccessful</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">App</span><span class="hljs-title">Listeners</span><span class="hljs-title">AdldapSyncRoles</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span><span class="hljs-title">Foundation</span><span class="hljs-title">Support</span><span class="hljs-title">Providers</span><span class="hljs-title">EventServiceProvider</span> <span class="hljs-keyword">as</span> <span class="hljs-title">ServiceProvider</span>; <span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span><span class="hljs-title">Support</span><span class="hljs-title">Facades</span><span class="hljs-title">Event</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EventServiceProvider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ServiceProvider</span> </span>{ <span class="hljs-comment">/** * The event listener mappings for the application. * * <span class="hljs-doctag">@var</span> array<class-string, array<int, class-string>> */</span> <span class="hljs-keyword">protected</span> <span class="hljs-variable">$listen</span> = [ <span class="hljs-title class_">Registered</span>::<span class="hljs-variable language_">class</span> => [ <span class="hljs-title class_">SendEmailVerificationNotification</span>::<span class="hljs-variable language_">class</span>, ], <span class="hljs-title class_">AuthenticationSuccessful</span>::<span class="hljs-variable language_">class</span> => [ <span class="hljs-title class_">AdldapSyncRoles</span>::<span class="hljs-variable language_">class</span>, ], ];

<span class="hljs-comment">/**
 * Register any events for your application.
 *
 * <span class="hljs-doctag">@return</span> void
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">boot</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-comment">//</span>
}

}</pre></div><h2 id="cb10">Add a new LDAP user</h2><p id="9e50">Open the PHP LDAP admin on <a href="http://localhost:8080/">http://localhost:8080/</a> path and login with admin DN and password.</p><p id="3bf3"><b>Login DN:</b> cn=admin,dc=example,dc=org <b>Password:</b> admin</p><p id="1778">After login, click the “Create new entry here” under the cn<b>=</b>users</p><figure id="3f8e"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*h1t42N80DVVmQ9_HvrJYRQ.png"><figcaption></figcaption></figure><p id="e749">On create object screen click the “Generic: User Account”</p><figure id="2945"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*yxtwgNgVZh_v_VmVow-ttw.png"><figcaption></figcaption></figure><p id="6214">Create a new user and commit the changes.</p><figure id="3f2b"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*5Ie-_CSuyhfoxyJxLHdNnw.png"><figcaption></figcaption></figure><p id="2689">After that “Add new attribute” and add the Email address for the user.</p><figure id="2a91"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*EIzfTcKK_YQAbaJRvdrpiA.png"><figcaption></figcaption></figure><p id="bb4f">Now add this user to all the groups, by following the below step.</p><p id="dfd1">Click the “cn=users” on the sidebar menu and add the “<i>newuser</i>” by clicking the “add value” on <i>memberUid</i>.</p><figure id="fd6e"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*wnsXCXU2tCFUXbWLf-6K9Q.png"><figcaption></figcaption></figure><p id="437a">similarly, add the “<i>newuser</i>” to the admin and writer group.</p><h2 id="8a95">Login with a new user</h2><p id="eb9d">Login with the newly created LDAP user. After login verifies the user roles on the user edit page.</p><figure id="11ea"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*VZkVJ05QZ_EHt3dmnydNDw.png"><figcaption></figcaption></figure><p id="819f">The new user was created with admin and writer roles.</p><figure id="8887"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*NGdSq2m-cttWAvqrqgietg.png"><figcaption></figcaption></figure><h2 id="f1e0">Login Fallback</h2><blockquote id="0a34"><p>The login fallback option allows you to login as a user located in the local database if active directory authentication fails.</p></blockquote><p id="f445">This login fallback is only applicable to the DatabaseUserProvider.</p><p id="040b">Set the “LDAP_LOGIN_FALLBACK” value to true in env to enable the login fallback.</p><p id="6780">Thank you for reading.</p><p id="359d">Stay tuned for more!</p><p id="cde8"><i>Follow me at</i> <a href="https://balajidharma.medium.com/"><b><i>balajidharma.medium.com</i></b></a>.</p></article></body>

How to Assign a role to the user based on the LDAP group - Laravel LDAP authentication

Laravel LDAP authentication with an example — part 3

Photo by Proxyclick Visitor Management System on Unsplash

Last part we completed the LDAP login using the Adldap2-Laravel package. In this part, we going to add the roles to users based on the LDAP group.

Part 1: Laravel LDAP authentication — Laravel Docker install OpenLDAP and phpLDAPadmin Part 2: Laravel LDAP authentication — Laravel login with Open LDAP

Before we start the implementation we need to understand the basic concept of Events & Listeners.

Events & Listeners

Laravel’s events are a simple observer pattern, it allowing you to subscribe and listen for various events that occur within your application. The App\Providers\EventServiceProvider provides a convenient place to register all of your application's event listeners.

Generating Events & Listeners

The event:generate Artisan command is used to create a new Laravel event. Also, we can create Events & Listeners manually by creating files else add listeners and events to your EventServiceProvider

Alternatively, you may use the make:event and make:listener Artisan commands to generate individual events and listeners:

php artisan make:event PodcastProcessed
php artisan make:listener SendPodcastNotification --event=PodcastProcessed

List all Events

The event:list command is used to display a list of all events and listeners registered by your application.

./vendor/bin/sail artisan event:list


OutPut:

  Adldap\Laravel\Events\Authenticated ....................................................................................  
  ⇂ Adldap\Laravel\Listeners\LogAuthenticated  
  Adldap\Laravel\Events\AuthenticatedModelTrashed ........................................................................  
  ⇂ Adldap\Laravel\Listeners\LogTrashedModel  
  Adldap\Laravel\Events\AuthenticatedWithWindows .........................................................................  
  ⇂ Adldap\Laravel\Listeners\LogWindowsAuth  
  Adldap\Laravel\Events\Authenticating ...................................................................................  
  ⇂ Adldap\Laravel\Listeners\LogAuthentication  
  Adldap\Laravel\Events\AuthenticationFailed .............................................................................  
  ⇂ Adldap\Laravel\Listeners\LogAuthenticationFailure  
  Adldap\Laravel\Events\AuthenticationRejected ...........................................................................  
  ⇂ Adldap\Laravel\Listeners\LogAuthenticationRejection  
  Adldap\Laravel\Events\AuthenticationSuccessful .........................................................................  
  ⇂ Adldap\Laravel\Listeners\LogAuthenticationSuccess  
  Adldap\Laravel\Events\DiscoveredWithCredentials ........................................................................  
  ⇂ Adldap\Laravel\Listeners\LogDiscovery  
  Adldap\Laravel\Events\Importing ........................................................................................  
  ⇂ Adldap\Laravel\Listeners\LogImport  
  Adldap\Laravel\Events\Synchronized .....................................................................................  
  ⇂ Adldap\Laravel\Listeners\LogSynchronized  
  Adldap\Laravel\Events\Synchronizing ....................................................................................  
  ⇂ Adldap\Laravel\Listeners\LogSynchronizing  
  Illuminate\Auth\Events\Authenticated ...................................................................................  
  ⇂ Adldap\Laravel\Listeners\BindsLdapUserModel
  Illuminate\Auth\Events\Login ...........................................................................................  
  ⇂ Adldap\Laravel\Listeners\BindsLdapUserModel
  Illuminate\Auth\Events\Registered ......................................................................................  
  ⇂ Illuminate\Auth\Listeners\SendEmailVerificationNotification
  Illuminate\Database\Events\QueryExecuted ...............................................................................  
  ⇂ Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder@record
  Illuminate\Foundation\Events\LocaleUpdated .............................................................................  
  ⇂ Closure at: /vendor/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php:55
  Illuminate\Log\Events\MessageLogged ....................................................................................  
  ⇂ Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder@record
  Illuminate\Queue\Events\JobExceptionOccurred ...........................................................................  
  ⇂ Spatie\LaravelIgnition\Recorders\JobRecorder\JobRecorder@record
  Illuminate\Queue\Events\JobProcessed ...................................................................................  
  ⇂ Closure at: /vendor/spatie/laravel-ignition/src/IgnitionServiceProvider.php:273
  Illuminate\Queue\Events\JobProcessing ..................................................................................  
  ⇂ Closure at: /vendor/spatie/laravel-ignition/src/IgnitionServiceProvider.php:268

The above event:list output is listed all the Adldap\Laravel\Events.

So, we going to listen to one of the Adldap2-Laravel events. This event listener will save or update the user roles based on the LDAP group.

Create Event Listener for sync Role

We going to create the listener with the name AdldapSyncRoles by using the make:listener artisan command.

./vendor/bin/sail artisan make:listener AdldapSyncRoles

Open the app/Listeners/AdldapSyncRoles.php file and replace it with the below Role syncing-related changes. We going to listen to the Adldap AuthenticationSuccessful event. This event will trigger after the user is successfully authenticated with LDAP.

<?php

namespace App\Listeners;

use App\Models\Role;
use Adldap\Laravel\Events\AuthenticationSuccessful;
use Adldap\Laravel\Facades\Adldap;

class AdldapSyncRoles
{
    /**
     * Handle the event.
     *
     * @param AuthenticationSuccessful $event
     *
     * @return void
     */
    public function handle(AuthenticationSuccessful $event)
    {
        $assigned = [];
        $user_group = [];
        $uid = $event->user->getAttribute('uid')[0];
        $roles = Role::all();
        $groups = Adldap::search()->where('objectClass', 'posixGroup')->get();
        
        foreach ($groups as $group) {
            if(in_array($uid, $group->getAttribute('memberuid'))) {
                $user_group[] = $group->getAttribute('cn')[0];
            }
        }

        foreach ($roles as $role) {
            if (in_array($role->name, $user_group)) {
                $assigned[] = $role->id;
            }
        }

        $event->model->syncRoles($assigned);
    }
}

We using OpenLDAP, so we cannot use the $event->user->inGroup() method. So we manually fetched the groups and assigned the user group to the new array.

If you using any other Active Directory means (for Example Windows) use the below code

<?php

namespace App\Listeners;

use App\Users\Role;
use Adldap\Laravel\Events\AuthenticationSuccessful;

class SuccessfulLDAPLoginListener
{
    /**
     * Handle the event.
     *
     * @param AuthenticationSuccessful $event
     *
     * @return void
     */
    public function handle(AuthenticationSuccessful $event)
    {
        $assigned = [];
        $roles = Role::all();
        foreach ($roles as $role) {
            if ($event->user->inGroup($role->name)) {
                $assigned[] = $role->role_id;
            }
        }

        $event->model->syncRoles($assigned);
    }
}

Next step we going to check our role synching changes by adding a new user in PHP LDAP admin.

Registering new Listeners

Open the EventServiceProvider and add register our event and listener

app\Providers\EventServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Adldap\Laravel\Events\AuthenticationSuccessful;
use App\Listeners\AdldapSyncRoles;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        AuthenticationSuccessful::class => [
            AdldapSyncRoles::class,
        ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

Add a new LDAP user

Open the PHP LDAP admin on http://localhost:8080/ path and login with admin DN and password.

Login DN: cn=admin,dc=example,dc=org Password: admin

After login, click the “Create new entry here” under the cn=users

On create object screen click the “Generic: User Account”

Create a new user and commit the changes.

After that “Add new attribute” and add the Email address for the user.

Now add this user to all the groups, by following the below step.

Click the “cn=users” on the sidebar menu and add the “newuser” by clicking the “add value” on memberUid.

similarly, add the “newuser” to the admin and writer group.

Login with a new user

Login with the newly created LDAP user. After login verifies the user roles on the user edit page.

The new user was created with admin and writer roles.

Login Fallback

The login fallback option allows you to login as a user located in the local database if active directory authentication fails.

This login fallback is only applicable to the DatabaseUserProvider.

Set the “LDAP_LOGIN_FALLBACK” value to true in env to enable the login fallback.

Thank you for reading.

Stay tuned for more!

Follow me at balajidharma.medium.com.

Laravel
PHP
Open Source
Web Development
Development
Recommended from ReadMedium