Search code examples
symfonysecurityauthorizationfosuserbundleroles

fos user: allow route to many roles even if user have just one role


In my symfony project, using the FOS bundle, I have 4 roles like this:

  • ROLE_USER_ONE
  • ROLE_USER_TWO
  • ROLE_USER_THREE

They can't access to the same views, except for one. This is my controller for render the view:

/**
 * @Security("has_role('ROLE_USER_ONE', 'ROLE_USER_TWO', 'ROLE_USER_THREE')")
 * @Route("/add-note", name="add_user_note")
 * @Method({"GET"})
 */
public function addNoteToUserAction()
{
  $securityContext = $this->container->get('security.authorization_checker');

  if ($securityContext->isGranted('ROLE_USER_ONE', 'ROLE_USER_TWO', 'ROLE_USER_THREE')) {
    /* ... some persist datas and process here ... */
    return $this->render('MyBundle:NoteUser:addNote.html.twig', array(
    ));
  } else {
      throw new \Exception('You have no right to access this page');
  }
}

To test the view rendering, I create a user with role ROLE_USER_TWO. And when I render the view I have this error:

Expression "has_role('ROLE_USER_ONE', 'ROLE_USER_TWO', 'ROLE_USER_THREE')" denied access.

As I understand, Symfony expected the user have all the roles, how can I allow the view access to user which as at less one of these roles in my controller annotations and controller code?


Solution

  • Instead of trying to put every role into the same has_role() statement, you have to concatenate them with or like this:

    @Security("has_role('ROLE_USER_ONE') or has_role('ROLE_USER_TWO') or has_role('ROLE_USER_THREE')")
    

    This way, you are actually checking that the current user has at least one of these roles instead of all of them.