BookStackApp/BookStack · warning · SamlException

errors.saml_already_logged_in

Error message

errors.saml_already_logged_in

What it means

SamlException thrown when the user arriving at the SAML2 ACS callback is already logged into BookStack. processLoginCallback refuses to run the find-or-register flow for an authenticated session, redirecting to /login instead, to avoid hijacking or mixing existing sessions.

Source

Thrown at app/Access/Saml2Service.php:365

        if ($this->shouldSyncGroups()) {
            $userDetails['groups'] = $this->getUserGroups($samlAttributes);
        }

        if ($this->config['dump_user_details']) {
            throw new JsonDebugException([
                'id_from_idp'         => $samlID,
                'attrs_from_idp'      => $samlAttributes,
                'attrs_after_parsing' => $userDetails,
            ]);
        }

        if (empty($userDetails['email'])) {
            throw new SamlException(trans('errors.saml_no_email_address'));
        }

        if ($isLoggedIn) {
            throw new SamlException(trans('errors.saml_already_logged_in'), '/login');
        }

        $user = $this->registrationService->findOrRegister(
            $userDetails['name'],
            $userDetails['email'],
            $userDetails['external_id']
        );

        if ($this->shouldSyncGroups()) {
            $this->groupSyncService->syncUserWithFoundGroups($user, $userDetails['groups'], $this->config['remove_from_groups']);
        }

        $this->loginService->login($user, 'saml2');

        return $user;
    }
}

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Simply log out of BookStack (or the browser session) before retrying SAML login, or navigate to /login and choose the normal route
  2. Guard the SAML login entry point in your app/redirect logic: if the user is already authenticated, skip calling /saml2/login and route them to the dashboard
  3. If this occurs on every login, check for mismatched session cookies (e.g. APP_URL vs actual host, or multiple BookStack instances sharing a cookie domain) that make BookStack think the user is logged in
  4. Clear cookies for the BookStack domain to remove stale authenticated sessions

Example fix

// before: blindly linking SAML login
<a href="/saml2/login">Login with SAML</a>
// after: only initiate SAML for guests
@auth <a href="/">Dashboard</a> @else <a href="/saml2/login">Login with SAML</a> @endauth
Defensive patterns

Strategy: validation

Validate before calling

// Only initiate SAML login for guests
if (auth()->check()) {
    return redirect('/'); // already logged in; skip /saml2/login
}

Type guard

function canInitiateSamlLogin(\Illuminate\Contracts\Auth\Guard $auth): bool
{
    return !$auth->check();
}

Try / catch

use BookStack\Exceptions\SamlException;

try {
    $saml->processLoginCallback();
} catch (SamlException $e) {
    if ($e->getMessage() === trans('errors.saml_already_logged_in')) {
        return redirect('/'); // or '/login' as the exception suggests
    }
    throw $e;
}

Prevention

When it happens

Trigger: A user with an active BookStack session initiates SAML login again (e.g. visits the /saml2/login route or an auto-initiated login while already authenticated) and completes the IdP round-trip; $isLoggedIn is true when processLoginCallback executes.

Common situations: User bookmarks the SAML login URL and clicks it while logged in; session remembered via 'remember me' while the IdP session also persists; an automated/auto-initiated IdP login (IdP-initiated SSO) triggered from an already-authenticated tab.

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/efb30efd9d939626. Report an issue: GitHub.