8000 [SecurityBundle] Fix referencing aliases from RegisterEntryPointPass · symfony/symfony@8dcc3d6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8dcc3d6

Browse files
committed
[SecurityBundle] Fix referencing aliases from RegisterEntryPointPass
1 parent fe57893 commit 8dcc3d6

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterEntryPointPass.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler;
1313

1414
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
15+
use Symfony\Component\DependencyInjection\ChildDefinition;
1516
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
1718
use Symfony\Component\DependencyInjection\Reference;
@@ -43,8 +44,13 @@ public function process(ContainerBuilder $container)
4344
continue;
4445
}
4546

47+
// because this pass runs before ResolveChildDefinitionPass, child definitions didn't inherit the parent class yet
4648
$definition = $container->findDefinition($authenticatorId);
47-
if (is_a($definition->getClass(), AuthenticationEntryPointInterface::class, true)) {
49+
while (!($authenticatorClass = $definition->getClass()) && $definition instanceof ChildDefinition) {
50+
$definition = $container->findDefinition($definition->getParent());
51+
}
52+
53+
if (is_a($authenticatorClass, AuthenticationEntryPointInterface::class, true)) {
4854
$entryPoints[$key] = $authenticatorId;
4955
}
5056
}

src/Symfony/Bundle/SecurityBundle/SecurityBundle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function build(ContainerBuilder $container)
7878
$container->addCompilerPass(new RegisterCsrfFeaturesPass());
7979
$container->addCompilerPass(new RegisterTokenUsageTrackingPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 200);
8080
$container->addCompilerPass(new RegisterLdapLocatorPass());
81-
$container->addCompilerPass(new RegisterEntryPointPass(), PassConfig::TYPE_BEFORE_REMOVING);
81+
$container->addCompilerPass(new RegisterEntryPointPass());
8282
// must be registered after RegisterListenersPass (in the FrameworkBundle)
8383
$container->addCompilerPass(new RegisterGlobalSecurityEventListenersPass(), PassConfig::TYPE_BEFORE_REMOVING, -200);
8484
// execute after ResolveChildDefinitionsPass optimization pass, to ensure class names are set
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Compiler;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterEntryPointPass;
16+
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
17+
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
18+
use Symfony\Component\DependencyInjection\ChildDefinition;
19+
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\HttpFoundation\JsonResponse;
21+
use Symfony\Component\HttpFoundation\Request;
22+
use Symfony\Component\HttpFoundation\Response;
23+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
24+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
25+
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
26+
use Symfony\Component\Security\Http\Authentication\AuthenticatorManager;
27+
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
28+
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
29+
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
30+
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
31+
32+
class RegisterEntryPointsPassTest extends TestCase
33+
{
34+
public function testProcessResolvesChildDefinitionsClass()
35+
{
36+
$container = new ContainerBuilder();
37+
38+
$container->setParameter('security.firewalls', ['main']);
39+
$container->setParameter('security.main._indexed_authenticators', ['custom' => 'security.authenticator.custom_authenticator.main']);
40+
41+
$container->register('security.authenticator.manager.main', AuthenticatorManager::class);
42+
$container->register('security.exception_listener.main', ExceptionListener::class)->setArguments([
43+
new AbstractArgument(),
44+
new AbstractArgument(),
45+
new AbstractArgument(),
46+
new AbstractArgument(),
47+
null, // entry point
48+
]);
49+
$config = $container->register('security.firewall.map.config.main', FirewallConfig::class);
50+
$config->setArguments([
51+
new AbstractArgument(),
52+
new AbstractArgument(),
53+
new AbstractArgument(),
54+
new AbstractArgument(),
55+
new AbstractArgument(),
56+
new AbstractArgument(),
57+
new AbstractArgument(),
58+
null, // entry point,
59+
]);
60+
61+
$container->register('custom_authenticator', CustomAuthenticator::class)
62+
->setAbstract(true);
63+
64+
$container->setDefinition('security.authenticator.custom_authenticator.main', new ChildDefinition('custom_authenticator'));
65+
66+
(new RegisterEntryPointPass())->process($container);
67+
68+
$this->assertSame('security.authenticator.custom_authenticator.main', $config->getArgument(7));
69+
}
70+
}
71+
72+
class CustomAuthenticator extends AbstractAuthenticator implements AuthenticationEntryPointInterface
73+
{
74+
public function supports(Request $request): ?bool
75+
{
76+
return false;
77+
}
78+
79+
public function authenticate(Request $request): PassportInterface
80+
{
81+
throw new BadCredentialsException();
82+
}
83+
84+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
85+
{
86+
return null;
87+
}
88+
89+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
90+
{
91+
return new JsonResponse([
92+
'error' => $exception->getMessageKey(),
93+
], JsonResponse::HTTP_FORBIDDEN);
94+
}
95+
96+
public function start(Request $request, AuthenticationException $authException = null)
97+
{
98+
}
99+
}

0 commit comments

Comments
 (0)
0