24Slides / laravel-saml2

[Laravel 5.4+] An integration to add SSO to your service via SAML2 protocol based on OneLogin toolkit with support of multiple Identity Providers
MIT License
231 stars 69 forks source link

Feature Request: Use Friendly Keys in URLs for Tenant Identification #103

Open MichMich opened 1 month ago

MichMich commented 1 month ago

Currently, tenants (SAML providers) are registered via Artisan commands and can be accessed through URLs like:

/saml2/b2dae2e6-e814-4553-a3a5-a56ddaca1110/login

While this works, I would prefer to use a more friendly identifier (such as a key) in the URLs, like:

/saml2/okta/login

To achieve this, I created a custom middleware that attempts to resolve the tenant by the friendly key and then falls back to the default UUID-based behavior if the key is not found. Here’s the code I used:

<?php

namespace App\Http\Middleware;

use Slides\Saml2\Repositories\TenantRepository;
use \Slides\Saml2\Http\Middleware\ResolveTenant;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class Saml2TenantKeyResolverMiddleware extends ResolveTenant
{
    public function handle($request, \Closure $next)
    {
        try {
            parent::handle($request, $next);
        } catch (NotFoundHttpException $e) {
            $tenant = (new TenantRepository)->findByKey($request->route('uuid'));
            if (!$tenant) throw $e;

            $request->route()->setParameter('uuid', $tenant->uuid);
            parent::handle($request, $next);
        }
    }
}

I also overrode the saml2.resolveTenant middleware in bootstrap/app.php like so:

return Application::configure(basePath: dirname(__DIR__))
    ->booted(function (Application $app) {
        $app['router']->aliasMiddleware('saml2.resolveTenant', \App\Http\Middleware\Saml2TenantKeyResolverMiddleware::class);
    })

Question:

Is there a cleaner or more integrated way to accomplish this, or perhaps a feature that could be added to the package to support friendly keys natively?

Thanks for your work on this package, and I appreciate any insights you might have!

sarisia commented 1 month ago

This seems really sucks but worked 🤔

$ php artisan db
mysql> update saml2_tenants set uuid='okta' where id=1;

Then all urls are now under /saml2/okta/[...]

MichMich commented 1 month ago

Yeah that probably works but seems like a dirty hack. Thanks for the suggestion though.

saboya commented 5 days ago

This would be relatively simple to add with a unique slug field. I did just that using the metadata field.

1 - Add a unique constraint to metadata->>slug (this is using Postgres):

create unique index saml2_tenants_metadata_slug_idx
    on public.saml2_tenants ((metadata ->> 'slug'::text));

2 - Create some route in your application such as /sso/{tenant_slug}/login 3 - In the controller, fetch the tenant by the metadata->>slug field and redirect to the UUID route.