Enable authentication if the LDAP server has multiple base DNs. Store the user's credentials in a cookie/session, and swap them out to the configured credentials when logged in.

This commit is contained in:
Deon George
2023-01-30 21:37:33 +11:00
parent 413f1ec065
commit 6751c9dd81
9 changed files with 236 additions and 24 deletions

20
app/Ldap/Connection.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
namespace App\Ldap;
use LdapRecord\Connection as ConnectionBase;
use LdapRecord\LdapInterface;
class Connection extends ConnectionBase
{
public function __construct($config = [], LdapInterface $ldap = null)
{
parent::__construct($config,$ldap);
// We need to override this so that we use our own Guard, that stores the users credentials in the session
$this->authGuardResolver = function () {
return new Guard($this->ldap, $this->configuration);
};
}
}

29
app/Ldap/Guard.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
namespace App\Ldap;
use Illuminate\Support\Facades\Cookie;
// use Illuminate\Support\Facades\Crypt;
use LdapRecord\Auth\Guard as GuardBase;
class Guard extends GuardBase
{
public function attempt($username, $password, $stayBound = false)
{
if ($result = parent::attempt($username,$password,$stayBound)) {
/*
* We can either use our session or cookies to store this. If using session, then Http/Kernel needs to be
* updated to start a session for API calls.
// We need to store our password so that we can swap in the user in during SwapinAuthUser::class middleware
request()->session()->put('username_encrypt',Crypt::encryptString($username));
request()->session()->put('password_encrypt',Crypt::encryptString($password));
*/
// For our API calls, we store the cookie - which our cookies are already encrypted
Cookie::queue('username_encrypt',$username);
Cookie::queue('password_encrypt',$password);
}
return $result;
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Ldap;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Str;
use LdapRecord\Laravel\Events\Auth\DiscoveredWithCredentials;
use LdapRecord\Laravel\LdapUserRepository as LdapUserRepositoryBase;
use LdapRecord\Models\Model;
class LdapUserRepository extends LdapUserRepositoryBase
{
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
*
* @return Model|null
* @throws \LdapRecord\Query\ObjectNotFoundException
*/
public function findByCredentials(array $credentials = []): ?Model
{
if (empty($credentials)) {
return NULL;
}
// Look for a user using all our baseDNs
foreach ((new Entry)->baseDNs() as $base) {
$query = $this->query()->setBaseDn($base);
foreach ($credentials as $key => $value) {
if (Str::contains($key, $this->bypassCredentialKeys)) {
continue;
}
if (is_array($value) || $value instanceof Arrayable) {
$query->whereIn($key, $value);
} else {
$query->where($key, $value);
}
}
if (! is_null($user = $query->first())) {
event(new DiscoveredWithCredentials($user));
return $user;
}
}
return NULL;
}
/**
* Get a user by their object GUID.
*
* @param string $guid
*
* @return Model|null
* @throws \LdapRecord\Query\ObjectNotFoundException
*/
public function findByGuid($guid): ?Model
{
// Look for a user using all our baseDNs
foreach ((new Entry)->baseDNs() as $base) {
$user = $this->query()->setBaseDn($base)->findByGuid($guid);
if ($user)
return $user;
}
return NULL;
}
}