laravelsaml-2.0

How to dynamically set Relay State using laravel-saml2?


I need to redirect the user to the same page he came from after the SAML authentication was successful. I've seen in various posts that I can use the RelayState param, for example:

how do I redirect back to the originally-requested url after authentication with passport-saml?

But how can I dynamically set it before sending the request to the IdP?

Right now, if a user is not logged in, he is redirected to the saml.login URL:

return route('saml.login', ['uuid' => 'some-uuid']);

But how can I set the RelayState parameter here as well? I want to pass the current URL and then when the ACS returns I want to redirect back to the URL he initially visited

The docs of this package don't mention anything about it: https://github.com/24Slides/laravel-saml2?tab=readme-ov-file

Update: Looking at the code, it looks like it searches for a pre-defined relay_state_url that needs to first be set in the DB for the tenant, however, I need it dynamic per user.

From the Saml2Controller code:

public function login(Request $request, Auth $auth)
{
    $redirectUrl = $auth->getTenant()->relay_state_url ?: config('saml2.loginRoute');

    $auth->login($request->query('returnTo', $redirectUrl));
}

(Source: https://github.com/24Slides/laravel-saml2/blob/master/src/Http/Controllers/Saml2Controller.php#L120)

Perhaps I need to create my own custom SamlController and use that instead? And there pass a custom $redirectUrl?


Solution

  • I found out how to do it!

    The login method of the Saml2Controller will redirect to the URL defined in the returnTo query string parameter, and it's defined in this method only by either the relay_state_url or the saml2.loginRoute (which are saved to the $redirectUrl variable):

    public function login(Request $request, Auth $auth)
    {
        $redirectUrl = $auth->getTenant()->relay_state_url ?: config('saml2.loginRoute');
    
        $auth->login($request->query('returnTo', $redirectUrl));
    }
    

    (Source: https://github.com/24Slides/laravel-saml2/blob/master/src/Http/Controllers/Saml2Controller.php#L120)

    However, the relay_state_url is hardcoded and fetched from the DB, and the loginRoute is hardcoded in the .env file, so neither will be dynamic.

    So what's needed to be done is to call the saml.login route with this query string parameter.

    In my case I did that via the Authenticate middleware:

    protected function redirectTo($request)
    {
        return route('saml.login', ['uuid' => 'some-uuid', 'returnTo' => $request->fullUrl()]);
    }
    

    This will generate the following URL:

    /saml2/some-uuid/login?returnTo=the-url-you-came-from
    

    and will redirect to the login method above with the returnTo URL, and will ignore the $redirectTo variable (This is how the Request's query() method works in Laravel: https://laravel.com/docs/12.x/requests#retrieving-input-from-the-query-string)