I am trying to add LDAP authentication to a BackPack-based application. I am following the same route as @realtebo here: How to use backpack-for-laravel with LdapRecord-Laravel?
The modified User Model looks like this:
<?php
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use LdapRecord\Laravel\Auth\LdapAuthenticatable;
use LdapRecord\Laravel\Auth\AuthenticatesWithLdap;
class User extends Authenticatable implements LdapAuthenticatable
{
use HasFactory;
use Notifiable;
use CrudTrait;
use HasRoles;
use AuthenticatesWithLdap;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
The configuration of the config.auth.providers looks like this:
'providers' => [
// https://ldaprecord.com/docs/laravel/v2/auth/database/configuration#introduction
'users' => [
'driver' => 'ldap',
'model' => LdapRecord\Models\ActiveDirectory\User::class,
'rules' => [],
'database' => [
'model' => App\Models\User::class,
'sync_passwords' => false,
'sync_attributes' => [
'name' => 'cn',
'email' => 'mail',
],
'sync_existing' => [
'email' => 'mail',
],
],
],
],
I have made sure to change the value of config.backpack.base.guard to null and also tried with 'web'. But unfortunately I still get this error: "These credentials do not match our records.".
The Ldap connection test returns success:
$ php artisan ldap:test
Testing LDAP connection [default]...
+------------+------------+--------------------------------------+-------------------------+---------------+
| Connection | Successful | Username | Message | Response Time |
+------------+------------+--------------------------------------+-------------------------+---------------+
| default | ✔ Yes | cn=read-only-admin,dc=example,dc=com | Successfully connected. | 209.32ms |
+------------+------------+--------------------------------------+-------------------------+---------------+
The logs from LdapRecord aren't of much use because this what I get:
[2022-02-02 11:59:34] local.INFO: LDAP (ldap://ldap.forumsys.com:389) - Operation: Binding - Username: cn=read-only-admin,dc=example,dc=com
[2022-02-02 11:59:34] local.INFO: LDAP (ldap://ldap.forumsys.com:389) - Operation: Bound - Username: cn=read-only-admin,dc=example,dc=com
[2022-02-02 11:59:34] local.INFO: LDAP (ldap://ldap.forumsys.com:389) - Operation: Search - Base DN: dc=example,dc=com - Filter: (&(objectclass=\74\6f\70)(objectclass=\70\65\72\73\6f\6e)(objectclass=\6f\72\67\61\6e\69\7a\61\74\69\6f\6e\61\6c\70\65\72\73\6f\6e)(objectclass=\75\73\65\72)(email=\70\61\73\74\65\75\72\40\6c\64\61\70\2e\66\6f\72\75\6d\73\79\73\2e\63\6f\6d)(!(objectclass=\63\6f\6d\70\75\74\65\72))) - Selected: (objectguid,*) - Time Elapsed: 317.31
Additional note regarding the LDAP queries: One thing I noticed about the LDAP query from the logs is that it uses the attribute email while the actual attribute in the directory is mail:
[
"objectclass" => [
"count" => 4,
0 => "inetOrgPerson",
1 => "organizationalPerson",
2 => "person",
3 => "top",
],
0 => "objectclass",
"sn" => [
"count" => 1,
0 => "Pasteur",
],
1 => "sn",
"cn" => [
"count" => 1,
0 => "Louis Pasteur",
],
2 => "cn",
"uid" => [
"count" => 1,
0 => "pasteur",
],
3 => "uid",
"telephonenumber" => [
"count" => 1,
0 => "602-214-4978",
],
4 => "telephonenumber",
"mail" => [
"count" => 1,
0 => "pasteur@ldap.forumsys.com",
],
5 => "mail",
"count" => 6,
"dn" => "uid=pasteur,dc=example,dc=com",
],
Brief update: making gradual progress; I realised the test LDAP server requires the OpenLDAP User model instead of ActiveDirectory. After changing the value for backpack.base.authentication_column to 'mail' and guard to 'web' the user can now authenticate.
Now this Exception is thrown:
Call to undefined method LdapRecord\Query\Model\OpenLdapBuilder::getTable() (View: /project_directory/vendor/backpack/crud/src/resources/views/base/inc/menu_user_dropdown.blade.php)
It look as if the LdapRecord User Model need to be modified. Is that correct?