Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[SecurityBundle] Fix Security::login() across firewalls#64338

Merged
nicolas-grekas merged 1 commit into
symfony:6.4symfony/symfony:6.4from
ousamabenyounes:fix/issue-53499ousamabenyounes/symfony:fix/issue-53499Copy head branch name to clipboard
May 23, 2026
Merged

[SecurityBundle] Fix Security::login() across firewalls#64338
nicolas-grekas merged 1 commit into
symfony:6.4symfony/symfony:6.4from
ousamabenyounes:fix/issue-53499ousamabenyounes/symfony:fix/issue-53499Copy head branch name to clipboard

Conversation

@ousamabenyounes
Copy link
Copy Markdown
Contributor

@ousamabenyounes ousamabenyounes commented May 23, 2026

Q A
Branch? 6.4
Bug fix? yes
New feature? no
Deprecations? no
Issues Fix #53499
License MIT

Security::login() is supposed to authenticate a user into the firewall passed as the third argument, but when that firewall differs from the one currently handling the request the new token ends up persisted under the current firewall's session key (_security_<currentFirewall>) instead of the target firewall's (_security_<targetFirewall>).

Root cause: ContextListener::onKernelResponse() keys its session write off $request->attributes->get('_security_firewall_run'), which is the current firewall's session key. After Security::login() minted a token for a different firewall, that listener writes the foreign token to the current firewall's bucket — so the user looks logged in to the wrong firewall.

Fix: when the target firewall differs from the current one, write the new token directly to the target firewall's session key (_security_<context>, mirroring what KernelBrowser::loginUser() does) and remove the _security_firewall_run request attribute so the current firewall's ContextListener does not overwrite its own bucket with the foreign token. The current firewall's existing token is therefore untouched.

The fix is a no-op when Security::login() is called for the firewall already handling the request, when the target firewall is stateless, or when the target firewall config cannot be resolved (e.g. on legacy setups without the new security.firewall_config_locator locator) — preserving full BC.

A new security.firewall_config_locator ServiceLocator (keyed by firewall name) is wired in SecurityExtension and injected into security.helper, alongside the existing security.user_checker_locator pattern.

Reproduces with Tests/Functional/SecurityTest::testLoginBetweenStatefulFirewalls.

TDD verification

  • RED (new test on 6.4 with Security.php/SecurityExtension.php/security.php reverted):
PHPUnit 9.6.21 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

There was 1 failure:

1) Symfony\Bundle\SecurityBundle\Tests\Functional\SecurityTest::testLoginBetweenStatefulFirewalls
Failed asserting that null is identical to Array &0 (
    'message' => 'Welcome back @chalasr'
).

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
  • GREEN (new test with the fix applied):
PHPUnit 9.6.21 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

OK (1 test, 1 assertion)

@nicolas-grekas
Copy link
Copy Markdown
Member

Thank you @ousamabenyounes.

@nicolas-grekas nicolas-grekas merged commit 1954a4b into symfony:6.4 May 23, 2026
9 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.