Skip to content

Commit d37c59f

Browse files
committed
Added CookieTokenStorage
1 parent 5d4a3a1 commit d37c59f

File tree

18 files changed

+484
-13
lines changed

18 files changed

+484
-13
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,19 @@ private function addCsrfSection(ArrayNodeDefinition $rootNode)
126126
->treatTrueLike(['enabled' => true])
127127
->treatNullLike(['enabled' => true])
128128
->addDefaultsIfNotSet()
129+
->beforeNormalization()
130+
->ifArray()
131+
->then(function ($v) {
132+
$v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
133+
134+
return $v;
135+
})
136+
->end()
129137
->children()
130-
// defaults to framework.session.enabled && !class_exists(FullStack::class) && interface_exists(CsrfTokenManagerInterface::class)
138+
// defaults to !class_exists(FullStack::class) && interface_exists(CsrfTokenManagerInterface::class)
131139
->booleanNode('enabled')->defaultNull()->end()
140+
// defaults to session if framework.session.enabled, cookie otherwise
141+
->scalarNode('storage')->defaultNull()->end()
132142
->end()
133143
->end()
134144
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@
107107
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
108108
use Symfony\Component\Security\Core\Security;
109109
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
110+
use Symfony\Component\Security\Csrf\EventListener\CookieTokenStorageListener;
111+
use Symfony\Component\Security\Csrf\TokenStorage\CookieTokenStorage;
112+
use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
110113
use Symfony\Component\Serializer\Encoder\DecoderInterface;
111114
use Symfony\Component\Serializer\Encoder\EncoderInterface;
112115
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
@@ -257,8 +260,11 @@ public function load(array $configs, ContainerBuilder $container)
257260
$this->registerRequestConfiguration($config['request'], $container, $loader);
258261
}
259262

263+
if (null === $config['csrf_protection']['storage']) {
264+
$config['csrf_protection']['storage'] = $this->sessionConfigEnabled || !class_exists(CookieTokenStorage::class) ? 'session' : 'cookie';
265+
}
260266
if (null === $config['csrf_protection']['enabled']) {
261-
$config['csrf_protection']['enabled'] = $this->sessionConfigEnabled && !class_exists(FullStack::class) && interface_exists(CsrfTokenManagerInterface::class);
267+
$config['csrf_protection']['enabled'] = ($this->sessionConfigEnabled || 'session' !== $config['csrf_protection']['storage']) && !class_exists(FullStack::class) && interface_exists(CsrfTokenManagerInterface::class);
262268
}
263269
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
264270

@@ -1450,12 +1456,31 @@ private function registerSecurityCsrfConfiguration(array $config, ContainerBuild
14501456
throw new LogicException('CSRF support cannot be enabled as the Security CSRF component is not installed. Try running "composer require symfony/security-csrf".');
14511457
}
14521458

1453-
if (!$this->sessionConfigEnabled) {
1454-
throw new \LogicException('CSRF protection needs sessions to be enabled.');
1455-
}
1456-
14571459
// Enable services for CSRF protection (even without forms)
14581460
$loader->load('security_csrf.xml');
1461+
switch ($config['storage']) {
1462+
case 'session':
1463+
if (!$this->sessionConfigEnabled) {
1464+
throw new \LogicException('CSRF protection needs sessions to be enabled.');
1465+
}
1466+
1467+
$container->setAlias('security.csrf.token_storage', SessionTokenStorage::class);
1468+
break;
1469+
case 'cookie':
1470+
if (!class_exists(CookieTokenStorage::class)) {
1471+
throw new LogicException('CSRF support with Cookie Storage is not installed. Try running "composer require symfony/security-csrf:^4.4".');
1472+
}
1473+
1474+
$container->setAlias('security.csrf.token_storage', CookieTokenStorage::class);
1475+
break;
1476+
default:
1477+
$container->setAlias('security.csrf.token_storage', $config['storage']);
1478+
break;
1479+
}
1480+
1481+
if ('cookie' !== $config['storage']) {
1482+
$container->removeDefinition(CookieTokenStorageListener::class);
1483+
}
14591484

14601485
if (!class_exists(CsrfExtension::class)) {
14611486
$container->removeDefinition('twig.extension.security_csrf');

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
<xsd:complexType name="csrf_protection">
5959
<xsd:attribute name="enabled" type="xsd:boolean" />
60+
<xsd:attribute name="storage" type="xsd:string" />
6061
</xsd:complexType>
6162

6263
<xsd:complexType name="esi">

src/Symfony/Bundle/FrameworkBundle/Resources/config/security_csrf.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@
1010
<service id="security.csrf.token_generator" class="Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator" />
1111
<service id="Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface" alias="security.csrf.token_generator" />
1212

13-
<service id="security.csrf.token_storage" class="Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage">
13+
<service id="Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage">
1414
<argument type="service" id="session" />
1515
</service>
16+
<service id="Symfony\Component\Security\Csrf\TokenStorage\CookieTokenStorage">
17+
<argument type="service" id="request_stack" />
18+
<argument>%kernel.secret%</argument>
19+
</service>
20+
<service id="Symfony\Component\Security\Csrf\EventListener\CookieTokenStorageListener">
21+
<argument type="service" id="security.csrf.token_storage"/>
22+
<tag name="kernel.event_subscriber" />
23+
</service>
1624
<service id="Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface" alias="security.csrf.token_storage" />
1725

1826
<service id="security.csrf.token_manager" class="Symfony\Component\Security\Csrf\CsrfTokenManager" public="true">

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ protected static function getBundleDefaultConfig()
215215
'ide' => null,
216216
'default_locale' => 'en',
217217
'csrf_protection' => [
218-
'enabled' => false,
218+
'enabled' => null,
219+
'storage' => null,
219220
],
220221
'form' => [
221222
'enabled' => !class_exists(FullStack::class),
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'session' => false,
5+
'csrf_protection' => [
6+
'enabled' => true,
7+
],
8+
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf_needs_session.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
$container->loadFromExtension('framework', [
44
'csrf_protection' => [
5-
'enabled' => true,
5+
'storage' => 'session',
66
],
77
]);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:framework="http://symfony.com/schema/dic/symfony"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
8+
9+
<framework:config>
10+
<framework:csrf-protection />
11+
</framework:config>
12+
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf_needs_session.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
88

99
<framework:config>
10-
<framework:csrf-protection />
10+
<framework:csrf-protection storage="session"/>
1111
</framework:config>
1212
</container>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
framework:
2+
csrf_protection: ~

0 commit comments

Comments
 (0)