Skip to content

Commit ee724b5

Browse files
javiereguiluzwouterj
authored andcommitted
Updated "Checking for Roles inside a Voter" for 2.8
1 parent ceb257f commit ee724b5

File tree

1 file changed

+10
-100
lines changed

1 file changed

+10
-100
lines changed

security/voters.rst

Lines changed: 10 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ decides this using whatever logic you want.
105105
  the ``security.authorization_checker`` service. The main difference is that
106106
when access is not granted, ``denyAccessUnlessGranted()`` throws an
107107
   ``AccessDeniedException``, whereas ``isGranted()`` returns ``false``.
108-
108+
109109
Creating the custom Voter
110110
-------------------------
111111

@@ -263,106 +263,16 @@ your voter will be executed and you can control access.
263263
Checking for Roles inside a Voter
264264
---------------------------------
265265

266-
.. versionadded:: 2.8
267-
The ability to inject the ``AccessDecisionManager`` is new in 2.8: it caused
268-
a CircularReferenceException before. In earlier versions, you must inject the
269-
``service_container`` itself and fetch out the ``security.authorization_checker``
270-
to use ``isGranted()``.
271-
272266
What if you want to call ``isGranted()`` from *inside* your voter - e.g. you want
273-
to see if the current user has ``ROLE_SUPER_ADMIN``. That's possible by injecting
274-
the :class:`Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManager`
275-
into your voter. You can use this to, for example, *always* allow access to a user
276-
with ``ROLE_SUPER_ADMIN``::
277-
278-
// src/AppBundle/Security/PostVoter.php
279-
280-
// ...
281-
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
282-
283-
class PostVoter extends Voter
284-
{
285-
// ...
286-
287-
private $decisionManager;
288-
289-
public function __construct(AccessDecisionManagerInterface $decisionManager)
290-
{
291-
$this->decisionManager = $decisionManager;
292-
}
293-
294-
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
295-
{
296-
// ...
297-
298-
// ROLE_SUPER_ADMIN can do anything! The power!
299-
if ($this->decisionManager->decide($token, array('ROLE_SUPER_ADMIN'))) {
300-
return true;
301-
}
302-
303-
// ... all the normal voter logic
304-
}
305-
}
306-
307-
Next, update ``services.yml`` to inject the ``security.access.decision_manager``
308-
service:
309-
310-
.. configuration-block::
311-
312-
.. code-block:: yaml
313-
314-
# app/config/services.yml
315-
services:
316-
app.post_voter:
317-
class: AppBundle\Security\PostVoter
318-
arguments: ['@security.access.decision_manager']
319-
public: false
320-
tags:
321-
- { name: security.voter }
322-
323-
.. code-block:: xml
324-
325-
<!-- app/config/services.xml -->
326-
<?xml version="1.0" encoding="UTF-8" ?>
327-
<container xmlns="http://symfony.com/schema/dic/services"
328-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
329-
xsi:schemaLocation="http://symfony.com/schema/dic/services
330-
http://symfony.com/schema/dic/services/services-1.0.xsd">
331-
332-
<services>
333-
<service id="app.post_voter"
334-
class="AppBundle\Security\PostVoter"
335-
public="false"
336-
>
337-
<argument type="service" id="security.access.decision_manager"/>
338-
339-
<tag name="security.voter" />
340-
</service>
341-
</services>
342-
</container>
343-
344-
.. code-block:: php
345-
346-
// app/config/services.php
347-
use AppBundle\Security\PostVoter;
348-
use Symfony\Component\DependencyInjection\Definition;
349-
use Symfony\Component\DependencyInjection\Reference;
350-
351-
$container->register('app.post_voter', PostVoter::class)
352-
->addArgument(new Reference('security.access.decision_manager'))
353-
->setPublic(false)
354-
->addTag('security.voter')
355-
;
356-
357-
That's it! Calling ``decide()`` on the ``AccessDecisionManager`` is essentially
358-
the same as calling ``isGranted()`` from a controller or other places
359-
(it's just a little lower-level, which is necessary for a voter).
360-
361-
.. note::
362-
363-
The ``security.access.decision_manager`` is private. This means you can't access
364-
it directly from a controller: you can only inject it into other services. That's
365-
ok: use ``security.authorization_checker`` instead in all cases except for voters.
267+
to see if the current user has ``ROLE_SUPER_ADMIN``. The ``isGranted()`` method
268+
is provided by the ``security.authorization_checker`` service via the
269+
:class:`Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManager`
270+
class. However, you can't inject that service because it causes a
271+
``CircularReferenceException``.
272+
273+
The solution is to inject the ``service_container`` service and use it to get
274+
the ``security.authorization_checker`` service and call to the ``isGranted()``
275+
method.
366276

367277
.. _security-voters-change-strategy:
368278

0 commit comments

Comments
 (0)