Skip to content

Commit a1e5f64

Browse files
committed
Merge branch '5.4' into 6.4
* 5.4: Add some informacion about why not using the Security service use access decision manager to control which token to vote on
2 parents b2d04ad + c9b77ef commit a1e5f64

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

security/impersonating_user.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,13 +376,14 @@ logic you want::
376376

377377
use Symfony\Bundle\SecurityBundle\Security;
378378
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
379+
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
379380
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
380381
use Symfony\Component\Security\Core\User\UserInterface;
381382

382383
class SwitchToCustomerVoter extends Voter
383384
{
384385
public function __construct(
385-
private Security $security,
386+
private AccessDecisionManager $accessDecisionManager,
386387
) {
387388
}
388389

@@ -401,12 +402,12 @@ logic you want::
401402
}
402403

403404
// you can still check for ROLE_ALLOWED_TO_SWITCH
404-
if ($this->security->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
405+
if ($this->accessDecisionManager->isGranted($token, ['ROLE_ALLOWED_TO_SWITCH'])) {
405406
return true;
406407
}
407408

408409
// check for any roles you want
409-
if ($this->security->isGranted('ROLE_TECH_SUPPORT')) {
410+
if ($this->accessDecisionManager->isGranted($token, ['ROLE_TECH_SUPPORT'])) {
410411
return true;
411412
}
412413

security/voters.rst

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,22 +241,22 @@ Checking for Roles inside a Voter
241241
---------------------------------
242242

243243
What if you want to call ``isGranted()`` from *inside* your voter - e.g. you want
244-
to see if the current user has ``ROLE_SUPER_ADMIN``. That's possible by injecting
245-
the :class:`Symfony\\Bundle\\SecurityBundle\\Security`
246-
into your voter. You can use this to, for example, *always* allow access to a user
244+
to see if the current user has ``ROLE_SUPER_ADMIN``. That's possible by using an
245+
:class:`access decision manager <Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManagerInterface>`
246+
inside your voter. You can use this to, for example, *always* allow access to a user
247247
with ``ROLE_SUPER_ADMIN``::
248248

249249
// src/Security/PostVoter.php
250250

251251
// ...
252-
use Symfony\Bundle\SecurityBundle\Security;
252+
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
253253

254254
class PostVoter extends Voter
255255
{
256256
// ...
257257

258258
public function __construct(
259-
private Security $security,
259+
private AccessDecisionManagerInterface $accessDecisionManager,
260260
) {
261261
}
262262

@@ -265,14 +265,33 @@ with ``ROLE_SUPER_ADMIN``::
265265
// ...
266266

267267
// ROLE_SUPER_ADMIN can do anything! The power!
268-
if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
268+
if ($this->accessDecisionManager->isGranted($token, ['ROLE_SUPER_ADMIN'])) {
269269
return true;
270270
}
271271

272272
// ... all the normal voter logic
273273
}
274274
}
275275

276+
.. caution::
277+
278+
In the previous example, avoid using the following code to check if a role
279+
is granted permission::
280+
281+
// DON'T DO THIS
282+
use Symfony\Component\Security\Core\Security;
283+
// ...
284+
285+
if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
286+
// ...
287+
}
288+
289+
The ``Security::isGranted()`` method inside a voter has a significant
290+
drawback: it does not guarantee that the checks are performed on the same
291+
token as the one in your voter. The token in the token storage might have
292+
changed or could change in the meantime. Always use the ``AccessDecisionManager``
293+
instead.
294+
276295
If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
277296
you're done! Symfony will automatically pass the ``security.helper``
278297
service when instantiating your voter (thanks to autowiring).

0 commit comments

Comments
 (0)