Adldap2 / Adldap2-Laravel

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

DatabaseUserProvider seems not to work with Oracle #536

Closed royalroot closed 6 years ago

royalroot commented 6 years ago
Laravel Version: 5.6
Adldap2-Laravel Version: 4.0
PHP Version: 7.1.10
LDAP Type: Active Directory

Description:

Hi again,

now I'm trying to use the DatabaseUserProvider with an oracle database. I used the migration tool "artisan migrate" to create the tables and changed the columns to which I needed. I can see in the debugbar, that the sqls are fired on the right table and on the right connection and also the right column "samaccountname", but i get this messy error message with a type error again:

"Type error: Argument 1 passed to Adldap\Laravel\Auth\DatabaseUserProvider::validateCredentials() must implement interface Illuminate\Contracts\Auth\Authenticatable, instance of App\Models\User given, called in /var/www/laravel/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php on line 380"

I think my config is wrong at some point.

Can you please help? I just wanted to sync a few attributes to the database and it ended in hours of trying :disappointed:

Here is my adldap_auth.php:

`<?php

return [

/*
|--------------------------------------------------------------------------
| Connection
|--------------------------------------------------------------------------
|
| The LDAP connection to use for laravel authentication.
|
| You must specify connections in your `config/adldap.php` configuration file.
|
| This must be a string.
|
*/

'connection' => env('ADLDAP_CONNECTION', 'default'),

/*
|--------------------------------------------------------------------------
| Provider
|--------------------------------------------------------------------------
|
| The LDAP authentication provider to use depending
| if you require database synchronization.
|
| For synchronizing LDAP users to your local applications database, use the provider:
|
| Adldap\Laravel\Auth\DatabaseUserProvider::class
|
| Otherwise, if you just require LDAP authentication, use the provider:
|
| Adldap\Laravel\Auth\NoDatabaseUserProvider::class
|
*/

'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class,

/*
|--------------------------------------------------------------------------
| Rules
|--------------------------------------------------------------------------
|
| Rules allow you to control user authentication requests depending on scenarios.
|
| You can create your own rules and insert them here.
|
| All rules must extend from the following class:
|
|   Adldap\Laravel\Validation\Rules\Rule
|
*/

'rules' => [

    // Denys deleted users from authenticating.

    Adldap\Laravel\Validation\Rules\DenyTrashed::class,

    // Allows only manually imported users to authenticate.

    // Adldap\Laravel\Validation\Rules\OnlyImported::class,

],

/*
|--------------------------------------------------------------------------
| Scopes
|--------------------------------------------------------------------------
|
| Scopes allow you to restrict the LDAP query that locates
| users upon import and authentication.
|
| All scopes must implement the following interface:
|
|   Adldap\Laravel\Scopes\ScopeInterface
|
*/

'scopes' => [

    // Only allows users with a user principal name to authenticate.
    // Remove this if you're using OpenLDAP.
    Adldap\Laravel\Scopes\UpnScope::class,

    // Only allows users with a uid to authenticate.
    // Uncomment if you're using OpenLDAP.
    // Adldap\Laravel\Scopes\UidScope::class,

],

'usernames' => [

    /*
    |--------------------------------------------------------------------------
    | LDAP
    |--------------------------------------------------------------------------
    |
    | Discover:
    |
    |   The discover value is the users attribute you would
    |   like to locate LDAP users by in your directory.
    |
    |   For example, using the default configuration below, if you're
    |   authenticating users with an email address, your LDAP server
    |   will be queried for a user with the a `userprincipalname`
    |   equal to the entered email address.
    |
    | Authenticate:
    |
    |   The authenticate value is the users attribute you would
    |   like to use to bind to your LDAP server.
    |
    |   For example, when a user is located by the above 'discover'
    |   attribute, the users attribute you specify below will
    |   be used as the username to bind to your LDAP server.
    |
    */

    'ldap' => [

        'discover' => 'samaccountname',

        'authenticate' => 'samaccountname',

    ],

    /*
    |--------------------------------------------------------------------------
    | Eloquent
    |--------------------------------------------------------------------------
    |
    | The value you enter is the database column name used for locating
    | the local database record of the authenticating user.
    |
    | If you're using a `username` column instead, change this to `username`.
    |
    | This option is only applicable to the DatabaseUserProvider.
    |
    */

    'eloquent' => 'samaccountname',

    /*
    |--------------------------------------------------------------------------
    | Windows Authentication Middleware (SSO)
    |--------------------------------------------------------------------------
    |
    | Discover:
    |
    |   The 'discover' value is the users attribute you would
    |   like to locate LDAP users by in your directory.
    |
    |   For example, if 'samaccountname' is the value, then your LDAP server is
    |   queried for a user with the 'samaccountname' equal to the value of
    |   $_SERVER['AUTH_USER'].
    |
    |   If a user is found, they are imported (if using the DatabaseUserProvider)
    |   into your local database, then logged in.
    |
    | Key:
    |
    |    The 'key' value represents the 'key' of the $_SERVER
    |    array to pull the users account name from.
    |
    |    For example, $_SERVER['AUTH_USER'].
    |
    */

    'windows' => [

        'discover' => 'samaccountname',

        'key' => 'AUTH_USER',

    ],

],

'passwords' => [

    /*
    |--------------------------------------------------------------------------
    | Password Sync
    |--------------------------------------------------------------------------
    |
    | The password sync option allows you to automatically synchronize users
    | LDAP passwords to your local database. These passwords are hashed
    | natively by Laravel using the bcrypt() method.
    |
    | Enabling this option would also allow users to login to their accounts
    | using the password last used when an LDAP connection was present.
    |
    | If this option is disabled, the local database account is applied a
    | random 16 character hashed password upon every login, and will
    | lose access to this account upon loss of LDAP connectivity.
    |
    | This option must be true or false and is only applicable
    | to the DatabaseUserProvider.
    |
    */

    'sync' => env('ADLDAP_PASSWORD_SYNC', false),

    /*
    |--------------------------------------------------------------------------
    | Column
    |--------------------------------------------------------------------------
    |
    | This is the column of your users database table
    | that is used to store passwords.
    |
    | Set this to `null` if you do not have a password column.
    |
    | This option is only applicable to the DatabaseUserProvider.
    |
    */

    'column' => 'password',

],

/*
|--------------------------------------------------------------------------
| Login Fallback
|--------------------------------------------------------------------------
|
| The login fallback option allows you to login as a user located on the
| local database if active directory authentication fails.
|
| Set this to true if you would like to enable it.
|
| This option must be true or false and is only
| applicable to the DatabaseUserProvider.
|
*/

'login_fallback' => env('ADLDAP_LOGIN_FALLBACK', false),

/*
|--------------------------------------------------------------------------
| Sync Attributes
|--------------------------------------------------------------------------
|
| Attributes specified here will be added / replaced on the user model
| upon login, automatically synchronizing and keeping the attributes
| up to date.
|
| The array key represents the users Laravel model key, and
| the value represents the users LDAP attribute.
|
| This option must be an array and is only applicable
| to the DatabaseUserProvider.
|
*/

'sync_attributes' => [

    'email' => 'mail',
    'lastname' => 'sn',
    'firstname' => 'givenName',
    'department' => 'department',
    'company' => 'company',
    'location' => 'l',

],

/*
|--------------------------------------------------------------------------
| Logging
|--------------------------------------------------------------------------
|
| User authentication attempts will be logged using Laravel's
| default logger if this setting is enabled.
|
| No credentials are logged, only usernames.
|
| This is usually stored in the '/storage/logs' directory
| in the root of your application.
|
| This option is useful for debugging as well as auditing.
|
| You can freely remove any events you would not like to log below,
| as well as use your own listeners if you would prefer.
|
*/

'logging' => [

    'enabled' => true,

    'events' => [

        \Adldap\Laravel\Events\Importing::class => \Adldap\Laravel\Listeners\LogImport::class,
        \Adldap\Laravel\Events\Synchronized::class => \Adldap\Laravel\Listeners\LogSynchronized::class,
        \Adldap\Laravel\Events\Synchronizing::class => \Adldap\Laravel\Listeners\LogSynchronizing::class,
        \Adldap\Laravel\Events\Authenticated::class => \Adldap\Laravel\Listeners\LogAuthenticated::class,
        \Adldap\Laravel\Events\Authenticating::class => \Adldap\Laravel\Listeners\LogAuthentication::class,
        \Adldap\Laravel\Events\AuthenticationFailed::class => \Adldap\Laravel\Listeners\LogAuthenticationFailure::class,
        \Adldap\Laravel\Events\AuthenticationRejected::class => \Adldap\Laravel\Listeners\LogAuthenticationRejection::class,
        \Adldap\Laravel\Events\AuthenticationSuccessful::class => \Adldap\Laravel\Listeners\LogAuthenticationSuccess::class,
        \Adldap\Laravel\Events\DiscoveredWithCredentials::class => \Adldap\Laravel\Listeners\LogDiscovery::class,
        \Adldap\Laravel\Events\AuthenticatedWithWindows::class => \Adldap\Laravel\Listeners\LogWindowsAuth::class,
        \Adldap\Laravel\Events\AuthenticatedModelTrashed::class => \Adldap\Laravel\Listeners\LogTrashedModel::class,

    ],
],

]; `

And this is my auth.php: `<?php

return [

/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/

'defaults' => [
    'guard' => 'web',
    'passwords' => 'users',
],

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],
],

/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/

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

/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/

'passwords' => [
    'users' => [
        'provider' => 'adldap',
        'table' => 'password_resets',
        'expire' => 60,
    ],
],

]; `

Thanks in advance, Nico

P.S.: Without database now all works like a charm :smiley:

stevebauman commented 6 years ago

Hi @nicro87,

It looks like your user model isn't extending the right class or implementing the right interface.

Your App\Models\User class must either extend from the Illuminate\Foundation\Auth\User class, or implement the Illuminate\Contracts\Auth\Authenticatable interface.

For example, make sure on your App\Models\User that it looks like:

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    // ...
}
royalroot commented 6 years ago

Hi @stevebauman , Thanks a lot, it worked as you described. I have another question. Is it possible to map the "samaccountname" attribute to another column like "username"? I know that I can sync it with an alias, but I don't think the login will work after that. I used "samaccountname" in the Login-Form as well and wonder if I can replace it by "username".

royalroot commented 6 years ago

Hi @stevebauman, i'll close this issue, because its solved. But can you please answer my question?

Thx Nico