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