Skip to content

Commit e2775a9

Browse files
committed
[SecurityBundle][Routing] Add LogoutRouteLoader
1 parent 43066ff commit e2775a9

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Deprecate `Security::ACCESS_DENIED_ERROR`, `AUTHENTICATION_ERROR` and `LAST_USERNAME` constants, use the ones on `SecurityRequestAttributes` instead
8+
* Add `LogoutRouteLoader`
89

910
6.3
1011
---

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
use Symfony\Component\PasswordHasher\Hasher\Pbkdf2PasswordHasher;
5050
use Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher;
5151
use Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher;
52+
use Symfony\Component\Routing\Loader\ContainerLoader;
5253
use Symfony\Component\Security\Core\Authorization\Strategy\AffirmativeStrategy;
5354
use Symfony\Component\Security\Core\Authorization\Strategy\ConsensusStrategy;
5455
use Symfony\Component\Security\Core\Authorization\Strategy\PriorityStrategy;
@@ -170,6 +171,11 @@ public function load(array $configs, ContainerBuilder $container)
170171
}
171172

172173
$this->createFirewalls($config, $container);
174+
175+
if (!$container::willBeAvailable('symfony/routing', ContainerLoader::class, ['symfony/security/bundle'])) {
176+
$container->removeDefinition('security.route_loader.logout');
177+
}
178+
173179
$this->createAuthorization($config, $container);
174180
$this->createRoleHierarchy($config, $container);
175181

@@ -307,7 +313,7 @@ private function createFirewalls(array $config, ContainerBuilder $container): vo
307313

308314
// load firewall map
309315
$mapDef = $container->getDefinition('security.firewall.map');
310-
$map = $authenticationProviders = $contextRefs = $authenticators = [];
316+
$map = $authenticationProviders = $contextRefs = $authenticators = $configs = [];
311317
foreach ($firewalls as $name => $firewall) {
312318
if (isset($firewall['user_checker']) && 'security.user_checker' !== $firewall['user_checker']) {
313319
$customUserChecker = true;
@@ -317,6 +323,8 @@ private function createFirewalls(array $config, ContainerBuilder $container): vo
317323

318324
[$matcher, $listeners, $exceptionListener, $logoutListener, $firewallAuthenticators] = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
319325

326+
$configs[] = new Reference($configId);
327+
320328
if (!$firewallAuthenticators) {
321329
$authenticators[$name] = null;
322330
} else {
@@ -354,6 +362,11 @@ private function createFirewalls(array $config, ContainerBuilder $container): vo
354362
if (!$customUserChecker) {
355363
$container->setAlias(UserCheckerInterface::class, new Alias('security.user_checker', false));
356364
}
365+
366+
$container
367+
->getDefinition('security.route_loader.logout')
368+
->replaceArgument(0, new IteratorArgument($configs))
369+
;
357370
}
358371

359372
private function createFirewall(ContainerBuilder $container, string $id, array $firewall, array &$authenticationProviders, array $providerIds, string $configId): array

src/Symfony/Bundle/SecurityBundle/Resources/config/security.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\SecurityBundle\CacheWarmer\ExpressionCacheWarmer;
1515
use Symfony\Bundle\SecurityBundle\EventListener\FirewallListener;
16+
use Symfony\Bundle\SecurityBundle\Routing\LogoutRouteLoader;
1617
use Symfony\Bundle\SecurityBundle\Security;
1718
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
1819
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
@@ -229,6 +230,12 @@
229230
service('security.token_storage')->nullOnInvalid(),
230231
])
231232

233+
->set('security.route_loader.logout', LogoutRouteLoader::class)
234+
->args([
235+
abstract_arg('Firewall config iterator'),
236+
])
237+
->tag('routing.route_loader')
238+
232239
// Provisioning
233240
->set('security.user.provider.missing', MissingUserProvider::class)
234241
->abstract()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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\Routing;
13+
14+
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
15+
use Symfony\Component\Routing\Route;
16+
use Symfony\Component\Routing\RouteCollection;
17+
18+
class LogoutRouteLoader
19+
{
20+
/**
21+
* @param iterable<FirewallConfig> $firewallConfigs
22+
*/
23+
public function __construct(
24+
private readonly iterable $firewallConfigs
25+
) {
26+
}
27+
28+
public function __invoke(): RouteCollection
29+
{
30+
$collection = new RouteCollection();
31+
32+
foreach ($this->firewallConfigs as $config) {
33+
if (!$logoutConfig = $config->getLogout()) {
34+
continue;
35+
}
36+
37+
$collection->add('_logout_'.$config->getName(), new Route($logoutConfig['path']));
38+
}
39+
40+
return $collection;
41+
}
42+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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\Routing;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\SecurityBundle\Routing\LogoutRouteLoader;
16+
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
17+
use Symfony\Component\Routing\Route;
18+
use Symfony\Component\Routing\RouteCollection;
19+
20+
class LogoutRouteLoaderTest extends TestCase
21+
{
22+
public function testLoad()
23+
{
24+
$loader = new LogoutRouteLoader([
25+
new FirewallConfig('dev', 'security.user_checker'),
26+
new FirewallConfig('main', 'security.user_checker', logout: ['path' => '/logout']),
27+
]);
28+
$collection = $loader();
29+
30+
self::assertInstanceOf(RouteCollection::class, $collection);
31+
self::assertCount(1, $collection);
32+
self::assertEquals(new Route('/logout'), $collection->get('_logout_main'));
33+
}
34+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy