laravel-saml2 icon indicating copy to clipboard operation
laravel-saml2 copied to clipboard

Multiple IdPs with different config?

Open kw-pr opened this issue 3 years ago • 6 comments

My application uses 3 different IdPs. They all need a different configuration for example in the 'security' section.

To me it looks like you are using the same config/saml2.php for all tenants and only change 4 values (entityId, singleSignOnService, singleLogoutService, x509cert) Source.

Is this correct or did I miss something?

Do you have plans to change this in the future? Are you interested in a PR for this feature? How would you approach this?

kw-pr avatar Oct 07 '22 10:10 kw-pr

So to be clear, do you want to be able to adjust any configuration?

breart avatar Nov 20 '22 12:11 breart

Yes, I would need to have individual configuration. I do have 2 onelogin/php-saml systems at the moment and about to add a 3. The first is connection to a Active Directory. the other two are for two SAP systems.

kw-pr avatar Nov 21 '22 05:11 kw-pr

@brezzhnev @kw-pr : I think this is related to https://github.com/24Slides/laravel-saml2/issues/43

And as I said there, it would be useful indeed to have a way to override any setting for a specific IdP (which was the case with aacotroneo/laravel-saml2.

What I ended up doing in the meantime is store the settings and create a new middleware that looks like this :

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Config;
use Slides\Saml2\Repositories\TenantRepository;

class OverrideSamlSpConfig
{
    public function __construct(protected TenantRepository $tenants)
    {
    }

    public function handle(Request $request, Closure $next)
    {
        if ($uuid = $request->route('uuid')) {
            $config = $this->tenants->findByUUID($uuid)->metadata['saml2_config'] ?? [];

            foreach(Arr::dot($config) as $path => $value) {
                Config::set('saml2.' . $path, $value);
            }
        }

        return $next($request);
    }
}

That I include in the 'saml' middlewares in App\Http\Kernel :

'saml' => [
    \Illuminate\Session\Middleware\StartSession::class,
    \App\Http\Middleware\OverrideSamlSpConfig::class,
],

You also need to make sure that it's loaded before the resolver middleware with $middlewarePriority in the same Kernel file :

protected $middlewarePriority = [
    \App\Http\Middleware\AuthenticateWithBearerToken::class,
    \App\Http\Middleware\Authenticate::class,
    \App\Http\Middleware\AddLogContext::class,
    \App\Http\Middleware\OverrideSamlSpConfig::class,
    \Slides\Saml2\Http\Middleware\ResolveTenant::class,
];

Then you can add the config in your idp metadata column like so :

{
  "saml2_config": {
    "security": {
      "requestedAuthnContext": false
    }
  }
}

Hope that can help someone.

nicolus avatar Nov 30 '23 18:11 nicolus

Totally understand the problem @nicolus. I'm currently working on the next major version and trying to solve this problem via "resolvers". You'll be able to either extend existing one or create your own. You can check out implementation here.

Let me know if that would solve the problem.

breart avatar Nov 30 '23 19:11 breart

So the idea is that I would make my own classes that implement ResolvesIdentityProvider or ResolvesIdpConfig and then bind them in my AppServiceProvider so they replace the default ones ?

If so, that sounds perfect, thanks !

nicolus avatar Dec 01 '23 07:12 nicolus

Yeah, almost like that, but instead of binding another dependency in the service provider, you would need to change the class reference using resolvers.config in the config/saml2.php

I thought that would be easier, but DI is also an option to consider.

breart avatar Dec 01 '23 10:12 breart