Skip to content

Commit d21e4a1

Browse files
committed
added a form extension to disable CSRF validation
1 parent a6eff7a commit d21e4a1

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public function getConfigTreeBuilder()
4141

4242
$rootNode
4343
->children()
44+
->scalarNode('disable_csrf_role')->defaultNull()->end()
4445
->arrayNode('access_denied_listener')
4546
->useAttributeAsKey('name')
4647
->prototype('boolean')->end()

DependencyInjection/FOSRestExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ public function load(array $configs, ContainerBuilder $container)
4242
$loader->load('util.xml');
4343
$loader->load('request.xml');
4444

45+
if (!empty($config['disable_csrf_role'])) {
46+
$loader->load('forms.xml');
47+
$container->setParameter('fos_rest.disable_csrf_role', $config['disable_csrf_role']);
48+
}
49+
4550
$container->setParameter('fos_rest.cache_dir', $config['cache_dir']);
4651

4752
$formats = array();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSRestBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.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 FOS\RestBundle\Form\Extension;
13+
14+
use Symfony\Component\Form\AbstractTypeExtension;
15+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
16+
use Symfony\Component\Security\Core\SecurityContextInterface;
17+
18+
/**
19+
* Class DisableCSRFExtension
20+
*
21+
* @author Grégoire Pineau
22+
*/
23+
class DisableCSRFExtension extends AbstractTypeExtension
24+
{
25+
private $securityContext;
26+
private $role;
27+
28+
public function __construct(SecurityContextInterface $securityContext, $role)
29+
{
30+
$this->securityContext = $securityContext;
31+
$this->role = $role;
32+
}
33+
34+
public function setDefaultOptions(OptionsResolverInterface $resolver)
35+
{
36+
if (!$this->securityContext->getToken()) {
37+
return;
38+
}
39+
40+
if (!$this->securityContext->isGranted($this->role)) {
41+
return;
42+
}
43+
44+
$resolver->setDefaults(array(
45+
'csrf_protection' => false,
46+
));
47+
}
48+
49+
public function getExtendedType()
50+
{
51+
return 'form';
52+
}
53+
}

Resources/config/forms.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<service id="fos_rest.form.extension.csrf_disable" class="FOS\RestBundle\Form\Extension\DisableCSRFExtension">
9+
<tag name="form.type_extension" alias="form" />
10+
<argument type="service" id="security.context" />
11+
<argument>%fos_rest.disable_csrf_role%</argument>
12+
</service>
13+
</services>
14+
</container>

Resources/doc/2-the-view-layer.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Step 2: The view layer
22
======================
3+
34
### Introduction
45

56
The view layer makes it possible to write `format` (html, json, xml, etc) agnostic
@@ -304,5 +305,19 @@ fos_rest:
304305
callback_param: false
305306
```
306307
308+
#### CSRF validation
309+
310+
When building a single application that should handle forms both via HTML forms as well
311+
as via a REST API, one runs into a problem with CSRF token validation. In most cases it
312+
is necessary to enable them for HTML forms, but it makes no sense to use them for a REST
313+
API. For this reason there is a form extension to disable CSRF validation for users
314+
with a specific role. This of course requires that REST API users authenticate themselves
315+
and get a special role assigned.
316+
317+
```yaml
318+
fos_rest:
319+
disable_csrf_role: ROLE_API
320+
```
321+
307322
## That was it!
308323
[Return to the index](index.md) or continue reading about [Listener support](3-listener-support.md).

Resources/doc/configuration-reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Full default configuration
33

44
```yaml
55
fos_rest:
6+
disable_csrf_role: ~
67
access_denied_listener:
78

89
# Prototype

0 commit comments

Comments
 (0)