Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 5 : @IsGranted on method annotation doesn't work on inherited role

I (obviously) searched for similar problems, but mine ain't none of them.

Here's my case :

  • I made a custom role : ROLE_SUPER_ADMIN
  • My actual user is admin, his only role is ROLE_SUPER_ADMIN
  • The role ROLE_SUPER_ADMIN inherits the ROLE_ADMIN (see below)
  • I'm trying to access /users/page/1
  • I got Access Denied by controller annotation @IsGranted(["ROLE_ADMIN", "ROLE_RESPONSIBLE"])

Here is my Controller :

//src/Controller/UserController.php

/**
 * @Route("/users")
 * @IsGranted("ROLE_USER")
 */
class UserController extends AbstractController
{
    private $security;
    private $mailer;


    public function __construct(Security $security, MailerInterface $mailer)
    {
        $this->security = $security;
        $this->mailer = $mailer;
    }

    /**
     * @Route("/page/{!page}", name="user_index", requirements={"page"="\d+"}, defaults={"page":1})
     * @IsGranted({"ROLE_ADMIN", "ROLE_RESPONSIBLE"})
     */
    public function index(Request $request, UserRepository $userRepository, int $page = 1): Response
    {
[....]
}

And my custom role hierarchy

config/packages/security.yaml

security:
    role_hierarchy:
        ROLE_RESPONSIBLE: ROLE_USER
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

I double checked every character just in case i had a typo, i don't...

I thought it was like a && evaluation (user had to got ROLE_ADMIN and ROLE_RESPONSIBLE).

EDIT: That was the problem, the default behavior is a && evaluation of each role in the array, i needed to use * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_RESPONSIBLE')")

I tried only with @IsGranted("ROLE_USER"), it worked but @IsGranted("ROLE_ADMIN") does not, and it's an inherited role

I (still) can't embed an image so take my word on that or see my proof here

Thanks in advance, mondays are mondays you know ...

like image 265
missing_semicolon Avatar asked Jan 13 '20 13:01

missing_semicolon


1 Answers

You're requiring the user be granted two roles. Change your hierarchy to make ROLE_SUPER_ADMIN inherit ROLE_RESPONSIBLE so you can remove it or change the annotation to :

/**
 * @Security("is_granted('ROLE_ADMIN') or is_granted('ROLE_RESPONSIBLE')")
 */
like image 73
Altherius Avatar answered Oct 05 '22 11:10

Altherius