Laravel Breeze

Introduction

Important: Before getting started, please complete the configuration guide.

Laravel Breeze provides basic authentication scaffolding out-of-the-box.

This guide will show you how to integrate LdapRecord-Laravel using this scaffolding.

Debugging

inside your config/ldap.php file, ensure you have logging enabled during the setup of authentication. Doing this will help you immensely in debugging connectivity and authentication issues.

If you encounter issues along the way, be sure to open your storage/logs directory after you attempt signing in to your application and see what issues may be occurring.

In addition, you may also run the below artisan command to test connectivity to your LDAP server:

php artisan ldap:test

Sessions

Before we begin, if you are using the database session driver, you must change the user_id column from its default type. This is due to LDAP Object GUID's being stored as the user's ID, which is not compatible with the unsigned big integer type:

From:

Schema::create('sessions', function (Blueprint $table) {
    // ...
    $table->foreignId('user_id')->nullable()->index();
    // ...
});

To:

Schema::create('sessions', function (Blueprint $table) {
    // ...
    $table->string('user_id')->nullable()->index();
    // ...
});

Login Request

For this example application, we will authenticate our LDAP users with their email address using the LDAP attribute mail.

For LdapRecord to properly locate the user in your directory during sign in, we will override the authenticate method in the LoginRequest, and pass in an array with the mail key (which is the attribute we are wanting to retrieve our LDAP users by) and the users password:

// app/Http/Requests/Auth/LoginRequest.php

/**
 * Attempt to authenticate the request's credentials.
 *
 * @return void
 *
 * @throws \Illuminate\Validation\ValidationException
 */
public function authenticate()
{
    $this->ensureIsNotRateLimited();

    $credentials = [
        'mail' => $this->email,
        'password' => $this->password,
    ];

    if (! Auth::attempt($credentials, $this->filled('remember'))) {
        RateLimiter::hit($this->throttleKey());

        throw ValidationException::withMessages([
            'email' => __('auth.failed'),
        ]);
    }

    RateLimiter::clear($this->throttleKey());
}

Blade Views

Once you have completed updating your LoginRequest.php class, you will then have to navigate to any Blade views that contain references to Auth::user(). Remember, when using plain authentication, LdapRecord models are returned, not Eloquent.

In the standard scaffolding, this occurs namely in the navigation.blade.php view:

From:

<!-- resources/views/layouts/navigation.blade.php -->

{{ Auth::user()->name }} {{ Auth::user()->email }}

To:

<!-- resources/views/layouts/navigation.blade.php -->

{{ Auth::user()->getName() }} {{ Auth::user()->getFirstAttribute('mail') }}

That's it! You are now ready to authenticate LDAP users into your application.

Using Usernames

To authenticate your users by their username we must adjust some scaffolded code generated by Laravel Breeze.

In the following example, we will authenticate users by their sAMAccountName.

Login Form

We will first need to update the input HTML field inside the scaffolded login.blade.php view:

From:

<!-- resources/views/auth/login.blade.php -->

<!-- Email Address -->
<div>
  <x-label for="email" :value="__('Email')" />

  <x-input
    id="email"
    class="block w-full mt-1"
    type="email"
    name="email"
    :value="old('email')"
    required
    autofocus
  />
</div>

To:

<!-- resources/views/auth/login.blade.php -->

<!-- Username -->
<div>
  <x-label for="username" :value="__('Username')" />

  <x-input
    id="username"
    class="block w-full mt-1"
    type="text"
    name="username"
    :value="old('username')"
    required
    autofocus
  />
</div>

Login Request

Lastly, we must adjust the rules() and authenticate() methods inside the scaffolded LoginRequest.php class:

From:

// app/Http/Requests/Auth/LoginRequest.php

public function rules()
{
    return [
        'email' => 'required|string|email',
        'password' => 'required|string',
    ];
}

public function authenticate()
{
    $this->ensureIsNotRateLimited();

    if (! Auth::attempt($request->only('email', 'password'), $this->filled('remember'))) {
        RateLimiter::hit($this->throttleKey());

        throw ValidationException::withMessages([
            'email' => __('auth.failed'),
        ]);
    }

    RateLimiter::clear($this->throttleKey());
}

To:

// app/Http/Requests/Auth/LoginRequest.php

public function rules()
{
    return [
        'username' => 'required|string',
        'password' => 'required|string',
    ];
}

public function authenticate()
{
    $this->ensureIsNotRateLimited();

    $credentials = [
        'samaccountname' => $this->username,
        'password' => $this->password,
    ];

    if (! Auth::attempt($credentials, $this->filled('remember'))) {
        RateLimiter::hit($this->throttleKey());

        throw ValidationException::withMessages([
            'username' => __('auth.failed'),
        ]);
    }

    RateLimiter::clear($this->throttleKey());
}

You are now ready to log in LDAP users by their username!

Generated on September 7, 2024
Edit on GitHub