Adldap2 / Adldap2-Laravel

LDAP Authentication & Management for Laravel
MIT License
911 stars 185 forks source link

How to authenticate both OpenLDAP + Active Directory users #665

Open houseofcoder opened 5 years ago

houseofcoder commented 5 years ago

Description:

Schema : OpenLDAP Provider : DatabaseUserProvider

We are using OpenLDAP as proxy to Active Directory for authentication of both OpenLDAP as well as AD users.

Login of OpenLDAP users works fine but in case of AD users, byCredentials method of UserResolver class returns instance of Entry class rather than User class, Same happens with OpenLDAP users if i change the Schema to ActiveDirectory.

So we have got this situation where we want to authenticate both OpenLDAP + AD users, I know this package is not made to handle such situations but what could be possible solution for our problem?

houseofcoder commented 5 years ago

I guess this is because of the ObjectClass which creates problem while model mapping.. How do i support multiple(ie. inetorgperson/person) ObjectClass for ldap record?

@stevebauman Please suggest some workaround

houseofcoder commented 5 years ago

@stevebauman We tried your solution which was provided here https://github.com/Adldap2/Adldap2-Laravel/issues/230#issuecomment-272877162 but it did not worked.

Tried another workaround,

Since all emails of active directory users are of same domain(eg. xxx@abc.com)

So on the basis of email domain we switched the schema in adldap config file. Below is the change from ../config/adldap.php

$schema = Adldap\Schemas\OpenLDAP::class;
if( isset($_POST['email']) && strstr($email, '@') == '@abc.com')
{
    $schema = Adldap\Schemas\ActiveDirectory::class;
}

return [
    'connections' => [
        'default' => [
            'auto_connect' => env('ADLDAP_AUTO_CONNECT', true),
            'connection' => Adldap\Connections\Ldap::class,
            'schema' => $schema,
            'connection_settings' => [
                'account_prefix' => env('ADLDAP_ACCOUNT_PREFIX', ''),
                'account_suffix' => env('ADLDAP_ACCOUNT_SUFFIX', ''),
                'domain_controllers' => explode(' ', env('ADLDAP_CONTROLLERS', 'xyz.abc.com')),
                'port' => env('ADLDAP_PORT', 389),
                'timeout' => env('ADLDAP_TIMEOUT', 5),
                'base_dn' => env('ADLDAP_BASEDN', 'dc=abc,dc=com'),
                'admin_account_prefix' => env('ADLDAP_ADMIN_ACCOUNT_PREFIX', ''),
                'admin_account_suffix' => env('ADLDAP_ADMIN_ACCOUNT_SUFFIX', ''),
                'admin_username' => env('ADLDAP_ADMIN_USERNAME', 'cn=admin,dc=abc,dc=com'),
                'admin_password' => env('ADLDAP_ADMIN_PASSWORD', 'xxxxxxxxxxx'),
                'follow_referrals' => false,
                'use_ssl' => env('ADLDAP_USE_SSL', false),
                'use_tls' => env('ADLDAP_USE_TLS', true),
            ],
        ],
    ],
];

Above solution worked. Is it fine?

Issue exists in case of adldap:import command there we cannot switch between schema because $_POST won't be available when we run command from console.

Adding my buddy @kotaknishit in the discussion

houseofcoder commented 5 years ago

In case of adldap:import command what we did is,

class SyncUsers extends Import
{
    protected $signature = 'SyncUsers {--t|ldaptype= : LDAP type for limiting users imported.}';
    ...
    ...
    public function getUsers() : array
    {
        if( $this->option('ldaptype') == "ad")
        {
            config(['adldap.connections.openldap.schema'=> \Adldap\Schemas\ActiveDirectory::class]);
        }

        /** @var \Adldap\Query\Builder $query */
        $query = Resolver::query();
        $users = $query->paginate()->getResults();
        return array_filter($users, function ($user) {
            return $user instanceof User;
        });
    }
}

php artisan SyncUsers --ldaptype="openldap" // openldap is just a place holder php artisan SyncUsers --ldaptype="ad"

This new command works fine.

Not considering 'user?' argument and '--filter' option at the moment because we are only concerned about importing all users from OpenLDAP/AD.

@stevebauman What are your thoughts on this workaround ?

By the way Thanks a lot for this awesome plugin :)