San Thapa San Thapa - 1 year ago 116
PHP Question

How to restrict access of action/method (of Controller) to specific user in Symfony?

Is there a way to restrict access to specific routes aka action/method of controller in Symfony based on user?

I am implementing FOSUserBundle for user management and it has roles for defining permission that works well if I have user with defined roles but if I want to restrict the page based on users I have to create role for every routes or are there any better approach.

I have looked into ACL and its perfect but I don't find solution for my case or am I missing something there.

Looking for some help and ideas.


@AJ Cerqueti - Answer can be quick fix but I am looking for better approach if any.

To be more specific is it possible to assign access permission for routes to user using ACL or some other better approach.




For simple needs like this you can create a security voter that fit exactly what you need (ACL's are usually used for complex needs also due to the not easy implementation).

Then you can use the voter in your controller like described in the docs:

// get a Post instance
$post = ...;

// keep in mind, this will call all registered security voters
if (false === $this->get('security.authorization_checker')->isGranted('view', $post)) {
    throw new AccessDeniedException('Unauthorised access!');

Read also How to Use Voters to Check User Permissions


Maybe will be better to know on how many routes you want to add this behavior but in any case (and if you want to avoid to add in every controller the @AJCerqueti code) you can use a Voter like in this simple example:

Voter Class:

// src/AppBundle/Security/Authorization/Voter/RouteVoter.php
namespace AppBundle\Security\Authorization\Voter;

use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;    

class RouteVoter implements VoterInterface
    private   $routes;

    public function __construct(array $routes = array())
        $this->routes        = $routes;

    public function supportsAttribute($attribute)
        // you won't check against a user attribute, so return true
        return true;

    public function supportsClass($class)
        // your voter supports all type of token classes, so return true
        return true;

    public function vote(TokenInterface $token, $object, array $attributes)
        // get get allowed routes from current logged in user 
        $userRoutes = $token->getUser()->getRoutes();

        // implement as you want the checks and return the related voter constant as below

        if (...) {# your implementation

            return VoterInterface::ACCESS_DENIED;    

        return VoterInterface::ACCESS_ABSTAIN;

Register the Voter:

<service id="security.access.route_voter"
     class="AppBundle\Security\Authorization\Voter\RouteVoter" public="false">
<argument type="collection">
<tag name="security.voter" />

Now change the access decision strategy accordingly with the docs.

Can this fit your needs?