DirectoryTree / LdapRecord-Laravel

Multi-domain LDAP Authentication & Management for Laravel.
https://ldaprecord.com/docs/laravel/v3
MIT License
512 stars 54 forks source link

[Question] Ldap model binding without GUID attribute #660

Closed Lucas-Justine closed 5 months ago

Lucas-Justine commented 5 months ago

Environment:

I have an OpenLdap server that doesn't provide a guid attribute or unique binary attribute, and as the only unique attribute is a number. The plugin applies the function that only takes a string or a binary attribute.

    /**
     * Returns the string variant of a binary GUID.
     *
     * @param  string  $binary
     * @return string|null
     */
    protected function binaryGuidToString($binary)
    {
        return Utilities::binaryGuidToString($binary);
    }

I'd like to know how to prevent it from trying to convert the number to a string. I managed to get around the problem by modifying the value in a attribute handler, but I don't think this is a good way to do it.

$database->guid_uidnumber = $ldap->getFirstAttribute('number');
stevebauman commented 5 months ago

Hi @Lucas-Justine,

Can you post your config/auth.php? You should be using the OpenLDAP\User model inside, which uses entryuuid as its GUID key.

If you need to customize that, extend the built in OpenLDAP\User model with your own, override the key, and then update your config/auth.php file:

use LdapRecord\Models\OpenLDAP\User as BaseUser;

class User extends BaseUser
{
    protected string $guidKey = 'number';
}
Lucas-Justine commented 5 months ago

This is my config/auth.php


    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        'ldap' => [
            'driver' => 'ldap',
            'model' =>  App\Ldap\User::class,
            'database' => [
                'model' => App\Models\User::class,
                'sync_passwords' => true,
                'sync_attributes' => \App\Ldap\AttributeHandler::class,
                'sync_existing' => [
                    'uid_number' => 'uidnumber',
                ],
            ],
        ],
    ],

The User class is a custom class i've created

<?php

namespace App\Ldap;

use LdapRecord\Models\Model;

class User extends Model
{
    protected $guidKey = 'uidnumber';

    /**
     * The object classes of the LDAP model.
     *
     * @var array
     */
    public static $objectClasses = [
        'angeliqueUser'
    ];
}

The problem is that, there is no operational or binary attribute in ldap that looks like a GUID (e.g: abdf4705-81d9-4d70-88d3-cc15d06de268). I only have a single unique attribute, the uidnumber, which is a number (e.g. 80065). Because of this, the uidnumber is registered in the database with a GUID form (e.g: 36363636-3636-3636-3634-3634313637) and it can't do the binding with the ldap model with the $user->ldap method.

I'll try with the OpenLdap user model instead of the generic Ldap/Model, but I think the problem is the lack of GUID in LDAP

stevebauman commented 5 months ago

Oh I see what you're saying. I believe you should be able to override the getConvertedGuid method on your LdapRecord model and it should all work:

class User extends Model
{
    public function getConvertedGuid(?string $guid = null): ?string
    {
        return $this->getFirstAttribute($this->guidKey);
    }
}
Lucas-Justine commented 5 months ago

Oh I see what you're saying. I believe you should be able to override the getConvertedGuid method on your LdapRecord model and it should all work:

class User extends Model
{
    public function getConvertedGuid(?string $guid = null): ?string
    {
        return $this->getFirstAttribute($this->guidKey);
    }
}

Thank you very much, it works

stevebauman commented 5 months ago

Awesome, glad you're up and running @Lucas-Justine! Thanks for the quick replies and the detailed issue.