Thavarajan's avatar

Multiple Authentication Guards?

Hi there, Good morning all, My company has a different set of users, and we want to move things to common login solutions, our app is in laravel, we already use passport as our API credentials manager

Now the task is we need to allow the users to use keycloak and as well as our app(passport) at the same time,

trying with the following plugin https://github.com/robsontenorio/laravel-keycloak-guard

if the user is login through keycloak, i am able to authenticate the login for keycloak user, but if the user is logged in through passport, I am not able to authenticate the passport user.

and this happens vise versa,

if the users of the passport are able to authenticate, then keycloak users are not able to authenticate

If anybody have idea about this problem, kindly suggest how to move things forward

0 likes
2 replies
rodrigo.pedra's avatar
Level 56

I didn't test it, but I think you can create a custom guard that calls both guards under the hood.

This should work, or at least give you a path:

namespace App;

use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Factory;
use Illuminate\Contracts\Auth\Guard;
use KeycloakGuard\KeycloakGuard;
use Laravel\Passport\Guards\TokenGuard;

class AppGuard implements Guard
{
    use GuardHelpers;

    private TokenGuard $passport;

    private KeycloakGuard $keycloak;

    public function __construct(Factory $auth)
    {
        $this->passport = $auth->guard('passport');
        $this->keycloak = $auth->guard('keycloak');
    }

    public function user()
    {
        if (! is_null($this->user)) {
            return $this->user;
        }

        $user = $this->passport->user()
            ?? $this->keycloak->user();

        return \tap($user, fn () => $this->setUser($user));
    }

    public function validate(array $credentials = [])
    {
        return $this->passport->validate($credentials)
            || $this->keycloak->validate($credentials);
    }

    public function setUser(Authenticatable $user)
    {
        $this->user = $user;
        $this->passport->setUser($user);
        $this->keycloak->setUser($user);
    }
}

Then you register this custom guard on a service provider and configure on your ./config/auth.php file, so your API routes use this guard.

You can find instructions on how to do it here in the docs:

https://laravel.com/docs/9.x/authentication#adding-custom-guards

1 like
rodrigo.pedra's avatar

Note that you still need to add the configuration for both KeyCloack and Passport guards to your ./config/auth.php file, as these guards are instantiated on the custom guard.

See each package docs on how to configure them.

You then add a third guard config for your "combo" guard and use that in your auth middleware.

Please or to participate in this conversation.