|
107 | 107 | use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
|
108 | 108 | use Symfony\Component\Security\Core\Security;
|
109 | 109 | 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; |
110 | 113 | use Symfony\Component\Serializer\Encoder\DecoderInterface;
|
111 | 114 | use Symfony\Component\Serializer\Encoder\EncoderInterface;
|
112 | 115 | use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
|
@@ -257,8 +260,11 @@ public function load(array $configs, ContainerBuilder $container)
|
257 | 260 | $this->registerRequestConfiguration($config['request'], $container, $loader);
|
258 | 261 | }
|
259 | 262 |
|
| 263 | + if (null === $config['csrf_protection']['storage']) { |
| 264 | + $config['csrf_protection']['storage'] = $this->sessionConfigEnabled || !class_exists(CookieTokenStorage::class) ? 'session' : 'cookie'; |
| 265 | + } |
260 | 266 | 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); |
262 | 268 | }
|
263 | 269 | $this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
264 | 270 |
|
@@ -1450,12 +1456,31 @@ private function registerSecurityCsrfConfiguration(array $config, ContainerBuild
|
1450 | 1456 | throw new LogicException('CSRF support cannot be enabled as the Security CSRF component is not installed. Try running "composer require symfony/security-csrf".');
|
1451 | 1457 | }
|
1452 | 1458 |
|
1453 |
| - if (!$this->sessionConfigEnabled) { |
1454 |
| - throw new \LogicException('CSRF protection needs sessions to be enabled.'); |
1455 |
| - } |
1456 |
| - |
1457 | 1459 | // Enable services for CSRF protection (even without forms)
|
1458 | 1460 | $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 | + } |
1459 | 1484 |
|
1460 | 1485 | if (!class_exists(CsrfExtension::class)) {
|
1461 | 1486 | $container->removeDefinition('twig.extension.security_csrf');
|
|
0 commit comments