8000 Fixed entry point resolving and guard entry point configuration · symfony/symfony@6870a18 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6870a18

Browse files
committed
Fixed entry point resolving and guard entry point configuration
1 parent c30d6f9 commit 6870a18

File tree

4 files changed

+139
-5
lines changed

4 files changed

+139
-5
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/GuardAuthenticationFactory.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
1313

1414
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
15+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1516
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1617
use Symfony\Component\DependencyInjection\ChildDefinition;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -118,10 +119,8 @@ public function createEntryPoint(ContainerBuilder $container, string $id, array
118119
try {
119120
return $this->determineEntryPoint(null, $config);
120121
} catch (\LogicException $e) {
121-
// ignore the exception, the new system prefers setting "entry_point" over "guard.entry_point"
122+
throw new InvalidConfigurationException(sprintf('Because you have multiple guard authenticators, you need to set the "entry_point" key to one of your authenticators (%s).', implode(', ', $config['authenticators'])));
122123
}
123-
124-
return null;
125124
}
126125

127126
private function determineEntryPoint(?string $defaultEntryPointId, array $config): string

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\DependencyInjection\Reference;
3434
use Symfony\Component\EventDispatcher\EventDispatcher;
3535
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
36+
use Symfony\Component\Ldap\Entry;
3637
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
3738
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
3839
use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder;
@@ -443,6 +444,9 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
443444
if (!$this->authenticatorManagerEnabled) {
444445
$authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders);
445446
} else {
447+
// $configuredEntryPoint is resolved into a service ID and stored in $defaultEntryPoint
448+
$configuredEntryPoint = $defaultEntryPoint;
449+
446450
// authenticator manager
447451
$authenticators = array_map(function ($id) {
448452
return new Reference($id);
@@ -543,7 +547,7 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
543547
$authenticationProviders[] = $authenticators;
544548
}
545549

546-
if ($factory instanceof EntryPointFactoryInterface && ($entryPoint = $factory->createEntryPoint($container, $id, $firewall[$key], null))) {
550+
if ($factory instanceof EntryPointFactoryInterface && ($entryPoint = $factory->createEntryPoint($container, $id, $firewall[$key]))) {
547551
$entryPoints[$key] = $entryPoint;
548552
}
549553
} else {

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

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@
1616
use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension;
1717
use Symfony\Bundle\SecurityBundle\SecurityBundle;
1818
use Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Fixtures\UserProvider\DummyProvider;
19+
use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\Security\EntryPointStub;
20+
use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AppCustomAuthenticator;
21+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1922
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
2023
use Symfony\Component\DependencyInjection\ContainerBuilder;
2124
use Symfony\Component\DependencyInjection\Reference;
2225
use Symfony\Component\ExpressionLanguage\Expression;
26+
use Symfony\Component\HttpFoundation\Request;
27+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
67E6 28+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
29+
use Symfony\Component\Security\Core\User\UserInterface;
2330
use Symfony\Component\Security\Core\User\UserProviderInterface;
31+
use Symfony\Component\Security\Guard\AuthenticatorInterface;
2432

2533
class SecurityExtensionTest extends TestCase
2634
{
@@ -413,6 +421,90 @@ public function testSwitchUserWithSeveralDefinedProvidersButNoFirewallRootProvid
413421
$this->assertEquals(new Reference('security.user.provider.concrete.second'), $container->getDefinition('security.authentication.switchuser_listener.foobar')->getArgument(1));
414422
}
415423

424+
/**
425+
* @dataProvider provideEntryPointFirewalls
426+
*/
427+
public function testAuthenticatorManagerEnabledEntryPoint(array $firewall, $entryPointId)
428+
{
429+
$container = $this->getRawContainer();
430+
$container->loadFromExtension('security', [
431+
'enable_authenticator_manager' => true,
432+
'providers' => [
433+
'first' => ['id' => 'users'],
434+
],
435+
436+
'firewalls' => [
437+
'main' => $firewall,
438+
],
439+
]);
440+
441+
$container->compile();
442+
443+
$this->assertEquals($entryPointId, (string) $container->getDefinition('security.firewall.map.config.main')->getArgument(7));
444+
$this->assertEquals($entryPointId, (string) $container->getDefinition('security.exception_listener.main')->getArgument(4));
445+
}
446+
447+
public function provideEntryPointFirewalls()
448+
{
449+
// only one entry point available
450+
yield [['http_basic' => true], 'security.authentication.basic_entry_point.main'];
451+
// explicitly configured by authenticator key
452+
yield [['form_login' => true, 'http_basic' => true, 'entry_point' => 'form_login'], 'security.authentication.form_entry_point.main'];
453+
// explicitly configured another service
454+
yield [['form_login' => true, 'entry_point' => EntryPointStub::class], EntryPointStub::class];
455+
// no entry point required
456+
yield [['json_login' => true], null];
457+
458+
// only one guard authenticator entry point available
459+
yield [[
460+
'guard' => ['authenticators' => [AppCustomAuthenticator::class]],
461+
], AppCustomAuthenticator::class];
462+
// explicitly configured guard authenticator entry point
463+
yield [[
464+
'guard' => [
465+
'authenticators' => [AppCustomAuthenticator::class, NullAuthenticator::class],
466+
'entry_point' => NullAuthenticator::class,
467+
],
468+
], NullAuthenticator::class];
469+
}
470+
471+
/**
472+
* @dataProvider provideEntryPointRequiredData
473+
*/
474+
public function testEntryPointRequired(array $firewall, $messageRegex)
475+
{
476+
$this->expectException(InvalidConfigurationException::class);
477+
$this->expectExceptionMessageMatches($messageRegex);
478+
479+
$container = $this->getRawContainer();
480+
$container->loadFromExtension('security', [
481+
'enable_authenticator_manager' => true,
482+
'providers' => [
483+
'first' => ['id' => 'users'],
484+
],
485+
486+
'firewalls' => [
487+
'main' => $firewall,
488+
],
489+
]);
490+
491+
$container->compile();
492+
}
493+
494+
public function provideEntryPointRequiredData()
495+
{
496+
// more than one entry point available and not explicitly set
497+
yield [
498+
['http_basic' => true, 'form_login' => true],
499+
'/^Because you have multiple authenticators in firewall "main", you need to set the "entry_point" key to one of your authenticators/',
500+
];
501+
// more than one guard entry point available and not explicitly set
502+
yield [
503+
['guard' => ['authenticators' => [AppCustomAuthenticator::class, NullAuthenticator::class]]],
504+
'/^Because you have multiple guard authenticators, you need to set the "entry_point" key to one of your authenticators/',
505+
];
506+
}
507+
416508
protected function getRawContainer()
417509
{
418510
$container = new ContainerBuilder();
@@ -439,3 +531,42 @@ protected function getContainer()
439531
return $container;
440532
}
441533
}
534+
535+
class NullAuthenticator implements AuthenticatorInterface
536+
{
537+
public function start(Request $request, AuthenticationException $authException = null)
538+
{
539+
}
540+
541+
public function supports(Request $request)
542+
{
543+
}
544+
545+
public function getCredentials(Request $request)
546+
{
547+
}
548+
549+
public function getUser($credentials, UserProviderInterface $userProvider)
550+
{
551+
}
552+
553+
public function checkCredentials($credentials, UserInterface $user)
554+
{
555+
}
556+
557+
public function createAuthenticatedToken(UserInterface $user, string $providerKey)
558+
{
559+
}
560+
561+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
562+
{
563+
}
564+
565+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
566+
{
567+
}
568+
569+
public function supportsRememberMe()
570+
{
571+
}
572+
}

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": "^7.2.5",
2020
"ext-xml": "*",
2121
"symfony/config": "^4.4|^5.0",
22-
"symfony/dependency-injection": "^4.4|^5.0",
22+
"symfony/dependency-injection": "^5.1",
2323
"symfony/event-dispatcher": "^5.1",
2424
"symfony/http-kernel": "^5.0",
2525
"symfony/polyfill-php80": "^1.15",

0 commit comments

Comments
 (0)
0