Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit be5eee5

Browse filesBrowse files
committed
Added CookieTokenStorage
1 parent 5d4a3a1 commit be5eee5
Copy full SHA for be5eee5

18 files changed

+484
-13
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+11-1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+30-5Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/security_csrf.xml
+9-1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+2-1Lines 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),
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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf_needs_session.php
+1-1Lines 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
]);
+12Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf_needs_session.xml
+1-1Lines 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>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
framework:
2+
csrf_protection: ~
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
framework:
2-
csrf_protection: ~
2+
csrf_protection:
3+
storage: session

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
4242
use Symfony\Component\Messenger\Transport\TransportFactory;
4343
use Symfony\Component\PropertyAccess\PropertyAccessor;
44+
use Symfony\Component\Security\Csrf\TokenStorage\CookieTokenStorage;
4445
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
4546
use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
4647
use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
@@ -131,6 +132,16 @@ public function testCsrfProtectionNeedsSessionToBeEnabled()
131132
$this->createContainerFromFile('csrf_needs_session');
132133
}
133134

135+
public function testCsrfProtectionFallbackToCookie()
136+
{
137+
if (!class_exists(CookieTokenStorage::class)) {
138+
$this->markTestSkipped('Cookie storage requires symfony/security 4.4+');
139+
}
140+
$container = $this->createContainerFromFile('csrf_fallback_to_cookie');
141+
142+
$this->assertSame(CookieTokenStorage::class, (string) $container->getAlias('security.csrf.token_storage'));
143+
}
144+
134145
public function testCsrfProtectionForFormsEnablesCsrfProtectionAutomatically()
135146
{
136147
$container = $this->createContainerFromFile('csrf');

‎src/Symfony/Component/Security/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212
for "guard" authenticators that deal with user passwords
1313
* Marked all dispatched event classes as `@final`
1414
* Deprecated returning a non-boolean value when implementing `Guard\AuthenticatorInterface::checkCredentials()`.
15+
* Added `CookieTokenStorage`
1516

1617
4.3.0
1718
-----
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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\Component\Security\Csrf\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
16+
use Symfony\Component\HttpKernel\KernelEvents;
17+
use Symfony\Component\Security\Csrf\TokenStorage\CookieTokenStorage;
18+
19+
/**
20+
* Inject transient cookies in the response.
21+
*
22+
* @author Oliver Hoff <oliver@hofff.com>
23+
* @author Jérémy Derussé <jeremy@derusse.com>
24+
*/
25+
class CookieTokenStorageListener implements EventSubscriberInterface
26+
{
27+
private $cookieTokenStorage;
28+
29+
public function __construct(CookieTokenStorage $cookieTokenStorage)
30+
{
31+
$this->cookieTokenStorage = $cookieTokenStorage;
32+
}
33+
34+
public function onKernelResponse(ResponseEvent $event)
35+
{
36+
$this->cookieTokenStorage->sendCookies($event->getResponse());
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
public static function getSubscribedEvents()
43+
{
44+
return [
45+
KernelEvents::RESPONSE => 'onKernelResponse',
46+
];
47+
}
48+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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\Component\Security\Csrf\Exception;
13+
14+
use Symfony\Component\Security\Core\Exception\RuntimeException as CoreRuntimeException;
15+
16+
/**
17+
* @author Jérémy Derussé <jeremy@derusse.com>
18+
*/
19+
class RuntimeException extends CoreRuntimeException
20+
{
21+
}

‎src/Symfony/Component/Security/Csrf/Exception/TokenNotFoundException.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Csrf/Exception/TokenNotFoundException.php
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
namespace Symfony\Component\Security\Csrf\Exception;
1313

14-
use Symfony\Component\Security\Core\Exception\RuntimeException;
15-
1614
/**
1715
* @author Bernhard Schussek <bschussek@gmail.com>
1816
*/

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.