cms icon indicating copy to clipboard operation
cms copied to clipboard

When using Saml2 Socialite provider callback page 404s

Open bland-industries opened this issue 1 year ago • 0 comments

Bug description

I set up Saml2 socialite provider. I clicked the "Log in with..." link on /cp. I authenticate with my identity provider and it redirects to oauth/saml2/callback that page 404s instead of getting logged in.

After I resolved the issue (see additional details) there are still issues with using saml2 as provider.

How to reproduce

set up a saml socialite provider (I am using Okta) and click the "Log in with..." link.

Logs

No response

Environment

PHP: 8.1.20
laravel/framework: v9.52.16
Statamic: 4.37.0
laravel/socialite: v5.11.0
socialiteproviders/saml2: 4.7.2



Environment
Laravel Version: 9.52.16
PHP Version: 8.1.20
Composer Version: 2.5.8
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: statamic
Database: mysql
Logs: errorlog
Mail: sendmail
Queue: sync
Session: file

Statamic
Addons: 20
Antlers: runtime
Stache Watcher: Disabled
Static Caching: Disabled
Version: 4.37.0 PRO

Statamic Addons
4rn0/statamic-v3-image-optimizer: 1.1.1
aryehraber/statamic-captcha: 1.10.0
aryehraber/statamic-logbook: 3.1.0
handmadeweb/statamic-cloudflare: 2.0.0
heidkaemper/statamic-toolbar: 1.1.2
jacksleight/statamic-bard-mutator: 2.3.0
jacksleight/statamic-bard-texstyle: 3.1.5
kind-work/two-fa: 1.5.1
rias/statamic-color-swatches: 2.2.0
rias/statamic-redirect: 3.6.1
roorda-ict/statamic-entries-export: 2.1.0
simonridley/tracking-code-manager: 1.0.2
statamic/collaboration: 0.7.3
stillat/relationships: 2.1.3
teamnovu/statamic-unused-assets: 2.0.1
webographen/statamic-admin-log: 1.0.8
webographen/statamic-widget-continue-editing: 1.1.0
withcandour/aardvark-seo: 3.0.1

Installation

Fresh statamic/statamic site via CLI

Antlers Parser

None

Additional details

After debugging the Saml response is a POST request and the statamic callback route is defined as GET.

The main gist of the solution would be to change the line in statamic web.php routes from Route::get(config('statamic.oauth.routes.callback'), [OAuthController::class, 'handleProviderCallback'])->name('oauth.callback'); to Route::any(config('statamic.oauth.routes.callback'), [OAuthController::class, 'handleProviderCallback'])->name('oauth.callback'); to handle any kind of response.

The next issue is that the OAuthController doesn't handle Saml2's stateless nature very well. Below is the route and code I put together to handle the some of the functionality as the controller.

// redirect code from OauthController::successRedirectUrl
// This doesn't redirect correctly back to the control panel
function successRedirectUrlHelper()
{
    $default = '/';

    $previous = session('_previous.url');

    if (! $query = array_get(parse_url($previous), 'query')) {
        return $default;
    }

    parse_str($query, $query);

    return array_get($query, 'redirect', $default);
}

Route::post('/oauth/saml2/callback', function () {
    $provider = 'saml2';

    // some code from Statamic\Http\Controllers\OauthController::handleProviderCallback
    // use stateless https://stackoverflow.com/questions/30660847/laravel-socialite-invalidstateexception second answer
    $providerUser = Socialite::driver($provider)->stateless()->user();

    $userData = [];

    // iterate over LiteSAML User assertion attributes
    // https://github.com/litesaml/lightsaml/blob/master/src/Model/Assertion/Attribute.php
    foreach ($providerUser->user as $attribute) {
        $userData[$attribute->getName()] = $attribute->getFirstAttributeValue();
    }

    // find a user the old fashioned way
    $user = User::query()
        ->where('email', $userData['email'])
        ->first();

    //handle user creation as needed

    // more code from OauthController::handleProviderCallback
    session()->put('oauth-provider', $provider);
    Auth::login($user, config('statamic.oauth.remember_me', true));

    return redirect()->to(successRedirectUrlHelper());
});

bland-industries avatar Feb 16 '24 18:02 bland-industries