skip to Main Content

I have a Laravel application with a simple multi-tenancy set-up. Every User belongs to an Account, and the User has an AccountScope; e.g. whenever a User is queried (User::where('name', 'like', "%query%")->get()) they will always be filtered on the logged-in user’s account_id.

I want to provide account admins with SSO in this application, I’m currently looking into Microsoft’s SSO. If one account wants to use their company’s Microsoft account’s SSO, and the other Account wants to use theirs, I’ll need them to provide their own client_id, client_secret and tenant_id.

I am trying to pass these values as variables, rather than coding them in config/services.php.

What I have so far is a route leading to this function:

use IlluminateSupportFacadesAuth;
use LaravelSocialiteFacadesSocialite;

public function microsoftLogin()
{
    $ssoSettings = Auth::user()->account->ssoSettings;

    return Socialite::driver('microsoft')
        ->with([
            'client_id' => $ssoSettings->client_id,
            'client_secret' => $ssoSettings->client_secret,
            'redirect_uri' => config('services.microsoft.redirect'),
            'tenant_id' => $ssoSettings->tenant_id,
        ])
        ->redirect();
}

Which still gives me the following error:

SocialiteProvidersManagerExceptionMissingConfigException: Missing services entry for microsoft.client_id

And building the provider like so:

use IlluminateSupportFacadesAuth;
use LaravelSocialiteFacadesSocialite;
use SocialiteProvidersMicrosoftMicrosoftExtendSocialite;

public function microsoftLogin()
{
    $ssoSettings = Auth::user()->account->ssoSettings;

    return Socialite::buildProvider(MicrosoftExtendSocialite::class, [
        'client_id' => $ssoSettings->client_id,
        'client_secret' => $ssoSettings->client_secret,
        'redirect_uri' => config('services.microsoft.redirect'),
        'tenant_id' => $ssoSettings->tenant_id,
    ])->redirect();
}

Which gives me:

ErrorException: Undefined array key "redirect"

The exception seems to be thrown on 'tenant_id' => $ssoSettings->tenant_id, which is all the more strange. config('services.microsoft.redirect') does give me the correct string.

How can I pass the Account’s SSO settings, overriding the ones from the .env/config?

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution with KejKej's answer; Microsoft in particular just has an odd naming scheme for their socialite provider. Here's my working code:

    use IlluminateSupportFacadesAuth;
    use LaravelSocialiteFacadesSocialite;
    use SocialiteProvidersMicrosoftProvider as MicrosoftProvider;
    
    public function microsoftLogin()
    {
        $ssoSettings = Auth::user()->account->ssoSettings;
    
        return Socialite::buildProvider(MicrosoftProvider::class, [
            'client_id' => $ssoSettings->client_id,
            'client_secret' => $ssoSettings->client_secret,
            'redirect' => config('services.microsoft.redirect'),
            'tenant_id' => $ssoSettings->tenant_id,
        ])->redirect();
    }
    

    There were two things I needed to fix in my code:

    1. Microsoft's provider can be found in the namespace SocialiteProvidersMicrosoftProvider. This is the class that needs to be passed to Socialite::buildProvider.
    2. The redirect URI's key has to be called 'redirect', as can be seen on the Socialite Providers Microsoft page

    I hope this helps future readers with a similar problem!


  2. You should use Socialite::buildProvider method. You can see how it works with the built-in providers, for example github

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search