Skip to content

Commit c9cebff

Browse files
committed
[Security] Add logout configuration for Clear-Site-Data header
1 parent 5f546fa commit c9cebff

File tree

9 files changed

+138
-2
lines changed

9 files changed

+138
-2
lines changed

DependencyInjection/MainConfiguration.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,15 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
251251
->scalarNode('path')->defaultValue('/logout')->end()
252252
->scalarNode('target')->defaultValue('/')->end()
253253
->booleanNode('invalidate_session')->defaultTrue()->end()
254+
->arrayNode('clear_site_data')
255+
->performNoDeepMerging()
256+
->beforeNormalization()->ifString()->then(fn ($v) => $v ? array_map('trim', explode(',', $v)) : [])->end()
257+
->enumPrototype()
258+
->values([
259+
'*', 'cache', 'cookies', 'storage', 'executionContexts',
260+
])
261+
->end()
262+
->end()
254263
->end()
255264
->fixXmlConfig('delete_cookie')
256265
->children()

DependencyInjection/SecurityExtension.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,13 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
480480
->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]);
481481
}
482482

483+
// add clear site data listener
484+
if ($firewall['logout']['clear_site_data'] ?? false) {
485+
$container->setDefinition('security.logout.listener.clear_site_data.'.$id, new ChildDefinition('security.logout.listener.clear_site_data'))
486+
->addArgument($firewall['logout']['clear_site_data'])
487+
->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]);
488+
}
489+
483490
// register with LogoutUrlGenerator
484491
$container
485492
->getDefinition('security.logout_url_generator')

Resources/config/schema/security-1.0.xsd

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,10 @@
171171
</xsd:complexType>
172172

173173
<xsd:complexType name="logout">
174-
<xsd:sequence>
174+
<xsd:choice minOccurs="0" maxOccurs="unbounded">
175175
<xsd:element name="delete-cookie" type="delete_cookie" minOccurs="0" maxOccurs="unbounded" />
176-
</xsd:sequence>
176+
<xsd:element name="clear-site-data" type="clear_site_data" minOccurs="0" maxOccurs="unbounded" />
177+
</xsd:choice>
177178
<xsd:attribute name="csrf-parameter" type="xsd:string" />
178179
<xsd:attribute name="csrf-token-generator" type="xsd:string" />
179180
<xsd:attribute name="csrf-token-id" type="xsd:string" />
@@ -407,4 +408,14 @@
407408
</xsd:simpleContent>
408409
</xsd:complexType>
409410

411+
<xsd:simpleType name="clear_site_data">
412+
<xsd:restriction base="xsd:string">
413+
<xsd:enumeration value="*" />
414+
<xsd:enumeration value="cache" />
415+
<xsd:enumeration value="cookies" />
416+
<xsd:enumeration value="storage" />
417+
<xsd:enumeration value="executionContexts" />
418+
</xsd:restriction>
419+
</xsd:simpleType>
420+
410421
</xsd:schema>

Resources/config/security_listeners.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Security\Http\Authentication\CustomAuthenticationSuccessHandler;
1818
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
1919
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
20+
use Symfony\Component\Security\Http\EventListener\ClearSiteDataLogoutListener;
2021
use Symfony\Component\Security\Http\EventListener\CookieClearingLogoutListener;
2122
use Symfony\Component\Security\Http\EventListener\DefaultLogoutListener;
2223
use Symfony\Component\Security\Http\EventListener\SessionLogoutListener;
@@ -64,6 +65,9 @@
6465
->set('security.logout.listener.session', SessionLogoutListener::class)
6566
->abstract()
6667

68+
->set('security.logout.listener.clear_site_data', ClearSiteDataLogoutListener::class)
69+
->abstract()
70+
6771
->set('security.logout.listener.cookie_clearing', CookieClearingLogoutListener::class)
6872
->abstract()
6973

Tests/DependencyInjection/CompleteConfigurationTestCase.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public function testFirewalls()
181181
'invalidate_session' => true,
182182
'delete_cookies' => [],
183183
'enable_csrf' => null,
184+
'clear_site_data' => [],
184185
],
185186
],
186187
[
@@ -708,6 +709,13 @@ public function testFirewallListenerWithProvider()
708709
$this->addToAssertionCount(1);
709710
}
710711

712+
public function testFirewallLogoutClearSiteData()
713+
{
714+
$container = $this->getContainer('logout_clear_site_data');
715+
$ClearSiteDataConfig = $container->getDefinition('security.firewall.map.config.main')->getArgument(12)['clear_site_data'];
716+
$this->assertSame(['cookies', 'executionContexts'], $ClearSiteDataConfig);
717+
}
718+
711719
protected function getContainer($file)
712720
{
713721
$file .= '.'.$this->getFileExtension();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
$container->loadFromExtension('security', [
4+
'providers' => [
5+
'default' => ['id' => 'foo'],
6+
],
7+
8+
'firewalls' => [
9+
'main' => [
10+
'provider' => 'default',
11+
'form_login' => true,
12+
'logout' => [
13+
'clear-site-data' => [
14+
'cookies',
15+
'executionContexts',
16+
],
17+
],
18+
],
19+
],
20+
]);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<srv:container xmlns="http://symfony.com/schema/dic/security"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:srv="http://symfony.com/schema/dic/services"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services
7+
https://symfony.com/schema/dic/services/services-1.0.xsd
8+
http://symfony.com/schema/dic/security
9+
https://symfony.com/schema/dic/security/security-1.0.xsd">
10+
11+
<config>
12+
<provider name="default" id="foo" />
13+
14+
<firewall name="main" provider="default">
15+
<form-login />
16+
<logout>
17+
<clear-site-data>cookies</clear-site-data>
18+
<clear-site-data>executionContexts</clear-site-data>
19+
</logout>
20+
</firewall>
21+
</config>
22+
</srv:container>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
security:
2+
providers:
3+
default:
4+
id: foo
5+
6+
firewalls:
7+
main:
8+
provider: default
9+
form_login: true
10+
logout:
11+
clear_site_data:
12+
- cookies
13+
- executionContexts

Tests/DependencyInjection/SecurityExtensionTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,48 @@ public function testConfigureCustomFirewallListener()
848848
$this->assertContains('custom_firewall_listener_id', $firewallListeners);
849849
}
850850

851+
public function testClearSiteDataLogoutListenerEnabled()
852+
{
853+
$container = $this->getRawContainer();
854+
855+
$firewallId = 'logout_firewall';
856+
$container->loadFromExtension('security', [
857+
'firewalls' => [
858+
$firewallId => [
859+
'logout' => [
860+
'clear_site_data' => ['*'],
861+
],
862+
],
863+
],
864+
]);
865+
866+
$container->compile();
867+
868+
$this->assertTrue($container->has('security.logout.listener.clear_site_data.'.$firewallId));
869+
$listenerArgument = $container->getDefinition('security.logout.listener.clear_site_data.'.$firewallId)->getArgument(0);
870+
$this->assertSame(['*'], $listenerArgument);
871+
}
872+
873+
public function testClearSiteDataLogoutListenerDisabled()
874+
{
875+
$container = $this->getRawContainer();
876+
877+
$firewallId = 'logout_firewall';
878+
$container->loadFromExtension('security', [
879+
'firewalls' => [
880+
$firewallId => [
881+
'logout' => [
882+
'clear_site_data' => [],
883+
],
884+
],
885+
],
886+
]);
887+
888+
$container->compile();
889+
890+
$this->assertFalse($container->has('security.logout.listener.clear_site_data.'.$firewallId));
891+
}
892+
851893
/**
852894
* @group legacy
853895
*/

0 commit comments

Comments
 (0)