Ldaprecord-laravel: Support Laravel Passport

Created on 16 Apr 2020  路  6Comments  路  Source: DirectoryTree/LdapRecord-Laravel

Most helpful comment

I've thought about this and have decided against it -- I think anyone needing this can create their own User model, extend the current one, then add these methods without much pain:

namespace App\Ldap;

use LdapRecord\Models\ActiveDirectory\User as BaseModel;

class User extends BaseModel
{
    public function findForPassport($username)
    {
        return $this->where('samaccountname', $username)->first();
    }

    public function findAndValidateForPassport($username, $password)
    {
        if(Auth::attempt(['samaccountname' => $username, 'password' => $password])) {
            return Auth::user();
        }
    }
}

The second method in the above example would be problematic as we would also have to assume they've successfully configured and enabled the LdapRecord auth driver as their default guard.

I also worry about adding this in because I would have to support it and answer any questions relating to it -- and I simply don't use passport for any project, so I am under-qualified to know if this is the best implementation, and how to troubleshoot.

If you or someone can provide an implementation with tests and documentation, I would absolutely merge it in, but for now I can't justify implementing it myself.

I hope that's understandable, thanks! :heart:

All 6 comments

Pasting this here for quick reference:

LdapRecord could support Passport out of the box if the following class include:

public function findForPassport($username)
{
    return $this->where('email', $username)->first();
}

public function findAndValidateForPassport($username, $password)
{
    if(Auth::attempt(['email' => $username, 'password' => $password])) {
        return Auth::user();
    }

I have changed it to use the username without the @test.email:

<?php

namespace App\Models;

use Illuminate\Support\Facades\Auth;
use Laravel\Passport\HasApiTokens;
use LdapRecord\Models\ActiveDirectory\User;

class ActiveDirectoryUser extends User
{
    public function findForPassport($username)
    {
        return $this->where('samaccountname', $username)->first();
    }

    public function findAndValidateForPassport($username, $password)
    {
        if(Auth::attempt(['samaccountname' => $username, 'password' => $password])) {
            return Auth::user();
        }
    }
}

Hi @brinkonaut!

I don't use Passport, but I absolutely want to integrate it if at all possible.

Would you be able to point me in the direction of how this adds compatibility with Passport?

If you add this functions to the class, passport will use them to resolve the user on every endpoint where you can use your credentials to receive tokens.
You can see here that passport will look in the model that is configured. It calls the findAndValidateForPassport function.

Then you don鈥檛 need to implement your own LoginController and can use the standard oauth endpoint. And the user do not need to login over the web LoginController first, I have tried that. So no need to sync users before they can login over oauth.

Ah perfect, exactly what I was looking for @brinkonaut, thanks!

Though we'll need to open up the ability to use any username, similarly how it is done right now with the LoginController since only Active Directory has the samaccountname attribute.

We could probably add this as a configurable property via:

protected $passportUsername = 'samaccountname';

public function findForPassport($username)
{
    return $this->where($this->passportUsername, $username)->first();
}

public function findAndValidateForPassport($username, $password)
{
    if(Auth::attempt([$this->passportUsername => $username, 'password' => $password])) {
        return Auth::user();
    }
}

Let me do some playing and see what I can come up with :smile:

I've thought about this and have decided against it -- I think anyone needing this can create their own User model, extend the current one, then add these methods without much pain:

namespace App\Ldap;

use LdapRecord\Models\ActiveDirectory\User as BaseModel;

class User extends BaseModel
{
    public function findForPassport($username)
    {
        return $this->where('samaccountname', $username)->first();
    }

    public function findAndValidateForPassport($username, $password)
    {
        if(Auth::attempt(['samaccountname' => $username, 'password' => $password])) {
            return Auth::user();
        }
    }
}

The second method in the above example would be problematic as we would also have to assume they've successfully configured and enabled the LdapRecord auth driver as their default guard.

I also worry about adding this in because I would have to support it and answer any questions relating to it -- and I simply don't use passport for any project, so I am under-qualified to know if this is the best implementation, and how to troubleshoot.

If you or someone can provide an implementation with tests and documentation, I would absolutely merge it in, but for now I can't justify implementing it myself.

I hope that's understandable, thanks! :heart:

I can understand this.
I think in most cases this is a solution, I have did it this way myself.
Maybe you can add this example to the docs.
Thank you for this awesome package 馃憤

Was this page helpful?
0 / 5 - 0 ratings