Skip to content

remember_organization cookie is never sent on successful LdapMulti/UserPassOrg login #2643

Description

@szabogyula

Describe the bug

When using an authentication source based on UserPassOrgBase (e.g. ldap:LdapMulti) with remember.organization.enabled => true, the "Remember my organization" checkbox is shown and checked, but the <authsource>-organization cookie is never sent to the browser on a successful login. The organization choice is therefore not remembered on the next visit.

To Reproduce

  1. Configure an ldap:LdapMulti authsource with remember.organization.enabled => true, remember.organization.checked => true, username_organization_method => none and a mapping of two orgs.
  2. Open the login page, select an organization, tick "Remember my organization", log in.
  3. Inspect the Set-Cookie headers on the core/loginuserpassorg POST response.

Expected: a Set-Cookie: <authsource>-organization=<org>; expires=<1 year>; ... header.
Actual: only the standard SimpleSAML and SimpleSAMLAuthToken session cookies are sent; no -organization cookie.

Root cause

In modules/core/src/Controller/Login.php, handleLogin() collects the organization cookie into a local $cookies[] array, calls $source::handleLogin(...), and only attaches the cookies to the response at the very end of the method (foreach ($cookies ...) { $t->headers->setCookie(...) } return $t;).

On a successful authentication, UserPassOrgBase::handleLogin() (and the LdapMulti override) calls Auth\Source::completeAuth($state), which redirects and does not return. The foreach block and return $t that attach the cookies are therefore never executed, so the Set-Cookie header is never generated. The cookie is only ever attached on the failure path, where the template is re-rendered — which is why the choice is never remembered after a successful login.

Environment

  • SimpleSAMLphp 2.x (master / 2.5.x-dev; the code path is identical in shipped 2.x releases)
  • simplesamlphp-module-ldap 2.0.x (ldap:LdapMulti)
  • PHP 8.2

Suggested fix

The cookies must be emitted before $source::handleLogin() is invoked, since that call redirects and never returns on success.

Option A: emit the collected cookies onto the outgoing response right before the try { $source::handleLogin(...) } call instead of at the end of the method, keeping the Symfony Cookie abstraction.

Option B: set the organization cookie directly after it is rendered, before the redirect:

setcookie(
    $source->getAuthId() . '-organization',
    $organization,
    [
        'expires'  => $expire,
        'path'     => '/',
        'secure'   => true,
        'httponly' => true,
        'samesite' => $sameSiteNone ?? 'Lax',
    ],
);

The same structural issue affects the remember-username cookie, which should be moved together with the organization cookie.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions