Skip to content

Commit 269a7a8

Browse files
committed
bug symfony#37366 [SecurityBundle] Fix UserCheckerListener registration with custom user checker (wouterj)
This PR was merged into the 5.1 branch. Discussion ---------- [SecurityBundle] Fix UserCheckerListener registration with custom user checker | Q | A | ------------- | --- | Branch? | 5.1 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix symfony#37365 | License | MIT | Doc PR | - The user checker listener was wrongly registered on the global event dispatcher, as it can be customized per firewall. This PR fixes that + correctly uses the configured user checker instead of always trying to use `UserCheckerInterface`. Commits ------- d63f590 Fix UserCheckerListener registration with custom user checkers
2 parents 0091864 + d63f590 commit 269a7a8

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

+6
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,12 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
478478
->replaceArgument(0, new Reference($managerId))
479479
;
480480

481+
// user checker listener
482+
$container
483+
->setDefinition('security.listener.user_checker.'.$id, new ChildDefinition('security.listener.user_checker'))
484+
->replaceArgument(0, new Reference('security.user_checker.'.$id))
485+
->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]);
486+
481487
$listeners[] = new Reference('security.firewall.authenticator.'.$id);
482488
}
483489

src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.xml

+2-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@
5454
<argument type="service" id="security.encoder_factory" />
5555
</service>
5656

57-
<service id="security.listener.user_checker" class="Symfony\Component\Security\Http\EventListener\UserCheckerListener">
58-
<tag name="kernel.event_subscriber" />
59-
<argument type="service" id="Symfony\Component\Security\Core\User\UserCheckerInterface" />
57+
<service id="security.listener.user_checker" class="Symfony\Component\Security\Http\EventListener\UserCheckerListener" abstract="true">
58+
<argument type="abstract">user checker</argument>
6059
</service>
6160

6261
<service id="security.listener.session"

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php

+47-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
use Symfony\Component\HttpFoundation\Response;
2828
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
2929
use Symfony\Component\Security\Core\Exception\AuthenticationException;
30+
use Symfony\Component\Security\Core\User\UserChecker;
31+
use Symfony\Component\Security\Core\User\UserCheckerInterface;
3032
use Symfony\Component\Security\Core\User\UserInterface;
3133
use Symfony\Component\Security\Core\User\UserProviderInterface;
3234
use Symfony\Component\Security\Guard\AuthenticatorInterface as GuardAuthenticatorInterface;
@@ -509,7 +511,7 @@ public function provideEntryPointRequiredData()
509511
];
510512
}
511513

512-
public function testAlwaysAuthenticateBeforeGrantingCannotBeTrueWithAuthenticationManager()
514+
public function testAlwaysAuthenticateBeforeGrantingCannotBeTrueWithAuthenticatorManager()
513515
{
514516
$this->expectException(InvalidConfigurationException::class);
515517
$this->expectExceptionMessage('The security option "always_authenticate_before_granting" cannot be used when "enable_authenticator_manager" is set to true. If you rely on this behavior, set it to false.');
@@ -559,7 +561,7 @@ public function provideConfigureCustomAuthenticatorData()
559561
];
560562
}
561563

562-
public function testCompilesWithoutSessionListenerWithStatelessFirewallWithAuthenticationManager()
564+
public function testCompilesWithoutSessionListenerWithStatelessFirewallWithAuthenticatorManager()
563565
{
564566
$container = $this->getRawContainer();
565567

@@ -580,7 +582,7 @@ public function testCompilesWithoutSessionListenerWithStatelessFirewallWithAuthe
580582
$this->assertFalse($container->has('security.listener.session.'.$firewallId));
581583
}
582584

583-
public function testCompilesWithSessionListenerWithStatefulllFirewallWithAuthenticationManager()
585+
public function testCompilesWithSessionListenerWithStatefulllFirewallWithAuthenticatorManager()
584586
{
585587
$container = $this->getRawContainer();
586588

@@ -601,6 +603,37 @@ public function testCompilesWithSessionListenerWithStatefulllFirewallWithAuthent
601603
$this->assertTrue($container->has('security.listener.session.'.$firewallId));
602604
}
603605

606+
/**
607+
* @dataProvider provideUserCheckerConfig
608+
*/
609+
public function testUserCheckerWithAuthenticatorManager(array $config, string $expectedUserCheckerClass)
610+
{
611+
$container = $this->getRawContainer();
612+
$container->register(TestUserChecker::class);
613+
614+
$container->loadFromExtension('security', [
615+
'enable_authenticator_manager' => true,
616+
'firewalls' => [
617+
'main' => array_merge([
618+
'pattern' => '/.*',
619+
'http_basic' => true,
620+
], $config),
621+
],
622+
]);
623+
624+
$container->compile();
625+
626+
$userCheckerId = (string) $container->getDefinition('security.listener.user_checker.main')->getArgument(0);
627+
$this->assertTrue($container->has($userCheckerId));
628+
$this->assertEquals($expectedUserCheckerClass, $container->findDefinition($userCheckerId)->getClass());
629+
}
630+
631+
public function provideUserCheckerConfig()
632+
{
633+
yield [[], UserChecker::class];
634+
yield [['user_checker' => TestUserChecker::class], TestUserChecker::class];
635+
}
636+
604637
protected function getRawContainer()
605638
{
606639
$container = new ContainerBuilder();
@@ -689,3 +722,14 @@ public function supportsRememberMe()
689722
{
690723
}
691724
}
725+
726+
class TestUserChecker implements UserCheckerInterface
727+
{
728+
public function checkPreAuth(UserInterface $user)
729+
{
730+
}
731+
732+
public function checkPostAuth(UserInterface $user)
733+
{
734+
}
735+
}

0 commit comments

Comments
 (0)