Skip to content

Commit 98276c4

Browse files
authored
Docs for #7198 (#2170)
1 parent e92dae8 commit 98276c4

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

symfony/security.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,73 @@ Additionally, in some cases you need to perform security checks on the original
158158

159159
The value in the `previous_object` variable is cloned from the original object.
160160
Note that, by default, this clone is not a deep one (it doesn't clone relationships, relationships are references).
161-
To make a deep clone, [implement `__clone` method](https://www.php.net/manual/en/language.oop5.cloning.php) in the concerned resource class.
161+
To make a deep clone, [implement `__clone` method](https://www.php.net/manual/en/language.oop5.cloning.php) in the concerned resource class.i
162+
163+
## Controlling the response on `securityPostDenormalize`
164+
165+
By default, when a request for a write operation is made that doesn't meet the `securityPostDenormalize` requirements (i.e. the expression returns `false`), the values of those protected properties in the
166+
request data are silently discarded and not set on the object. Any properties the user does have permission to update will be updated and the request succeeds.
167+
168+
You can optionally instruct API Platform to instead return a 403 Access Denied response in such cases, by adding `throw_on_access_denied` as an extra property with a value of `true`:
169+
170+
<code-selector>
171+
172+
```php
173+
<?php
174+
// api/src/Entity/Book.php
175+
namespace App\Entity;
176+
177+
use ApiPlatform\Metadata\Get;
178+
use ApiPlatform\Metadata\Put;
179+
180+
#[Get]
181+
#[Put(
182+
securityPostDenormalize: "is_granted('ROLE_ADMIN') or (object.owner == user and previous_object.owner == user)",
183+
extraProperties: ['throw_on_access_denied' => true]
184+
)]
185+
class Book
186+
{
187+
// ...
188+
}
189+
```
190+
191+
```yaml
192+
# api/config/api_platform/resources.yaml
193+
resources:
194+
App\Entity\Book:
195+
operations:
196+
ApiPlatform\Metadata\Get: ~
197+
ApiPlatform\Metadata\GetCollectionPut:
198+
securityPostDenormalize: "is_granted('ROLE_ADMIN') or (object.owner == user and previous_object.owner == user)"
199+
extraProperties:
200+
throw_on_access_denied: true
201+
# ...
202+
```
203+
204+
```xml
205+
<?xml version="1.0" encoding="UTF-8" ?>
206+
<!-- api/config/api_platform/resources.xml -->
207+
208+
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
209+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
210+
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
211+
https://api-platform.com/schema/metadata/resources-3.0.xsd">
212+
<resource class="App\Entity\Book">
213+
<operations>
214+
<operation class="ApiPlatform\Metadata\Get" />
215+
<operation class="ApiPlatform\Metadata\Put">
216+
<securityPostDenormalize>is_granted('ROLE_ADMIN') or (object.owner == user and previous_object.owner == user)</securityPostDenormalize>
217+
<extraProperties>
218+
<property name="throw_on_access_denied" value="true" />
219+
</extraProperties>
220+
</operation>
221+
</operations>
222+
</resource>
223+
</resources>
224+
```
225+
226+
</code-selector>
227+
162228

163229
## Hooking Custom Permission Checks Using Voters
164230

0 commit comments

Comments
 (0)