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 of 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 of 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 of 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 login LDAP users by their username!