Buy
Buy

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

There are two main places where you can deny access. The first we just learned about: access_control in security.yaml:

security:
... lines 2 - 40
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
... lines 43 - 44

It's simple - just a regular expression and a role. It's the best way to protect entire areas of your site - like everything under /admin with ROLE_ADMIN.

I do use access controls for things like that. But, most of the time, I prefer to control access at a more granular level. Open CommentAdminController. Most of the time, I deny access right inside the controller.

To test this out - let's comment-out our access control:

security:
... lines 2 - 40
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
... lines 43 - 44

Back in CommentAdminController, how can we deny access here? Simple: $this->denyAccessUnlessGranted() and pass this a role: ROLE_ADMIN:

... lines 1 - 10
class CommentAdminController extends Controller
{
... lines 13 - 15
public function index(CommentRepository $repository, Request $request, PaginatorInterface $paginator)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
... lines 19 - 32
}
}

That's it. Move over and refresh!

Nice! Try changing it to ROLE_USER:

... lines 1 - 10
class CommentAdminController extends Controller
{
... lines 13 - 15
public function index(CommentRepository $repository, Request $request, PaginatorInterface $paginator)
{
$this->denyAccessUnlessGranted('ROLE_USER');
... lines 19 - 32
}
}

Access granted! I love it!

IsGranted Annotation

But wait, there's more! As simple as this is, I like to use annotations. Check this out: delete the denyAccessUnlessGranted() code. Instead, above the method, add @IsGranted() to use an annotation that comes from SensioFrameworkExtraBundle: a bundle that we installed a long time ago via composer require annotations. In double quotes, pass ROLE_ADMIN:

... lines 1 - 6
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
... lines 8 - 11
class CommentAdminController extends Controller
{
/**
... line 15
* @IsGranted("ROLE_ADMIN")
*/
public function index(CommentRepository $repository, Request $request, PaginatorInterface $paginator)
{
... lines 20 - 32
}
}

Nice! Try it: refresh!

Access Denied by controller annotation

Pretty sweet. I know not everyone will love using annotations for this. So, if you don't love it, use the PHP version. No problem.

Protecting an Entire Controller Class

Oh, but the annotation does have one superpower. In addition to putting @IsGranted above a controller method, you can also put it above the controller class. Above CommmentAdminController, add @IsGranted("ROLE_ADMIN"):

... lines 1 - 6
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
... lines 8 - 11
/**
* @IsGranted("ROLE_ADMIN")
*/
class CommentAdminController extends Controller
{
... lines 17 - 35
}

Now, every method inside of this controller... which is only one right now, will require this role. When you refresh... yep! Same error. That is an awesome way to deny access.

We know how to make sure a user has a role. But, how can we simply make sure a user is logged in, regardless of roles? Let's find out next - and - create our first admin users.

Leave a comment!

  • 2018-09-28 Peter Kosak

    Yeaha, curly brackets work :) Thank you.

  • 2018-09-28 weaverryan

    > btw ryan you have to update email just saw it in IsGranted.php :)

    Ohh. I understand now! Yep, I'll probably have a lot of knpuniversity.com email addresses around in the code for a long time :p. But, that email does still work ;).

  • 2018-09-28 weaverryan

    Try this syntax:


    /**
    * @IsGranted({"ROLE_ADMIN","ROLE_MANAGER"})
    */

    If I remember correctly, you always use { } in annotations, never [ ] (even if it's an index array). If you'r egetting an error about the annotation not being installed, make sure you have the use statement for it:


    use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;

    The php-annotations plugin in PhpStorm auto-adds this for me when I auto-complete the annotation :).

    Cheers!

  • 2018-09-28 Peter Kosak

    when using this:


    /**
    * @IsGranted(["ROLE_ADMIN","ROLE_MANAGER"])
    */


    error:


    Exception thrown when handling an exception (Symfony\Component\Config\Exception\FileLoaderLoadException: [Syntax Error] Expected PlainValue, got '[' at position 11 in class App\Controller\ResourcePlanningController in /Users/peterkosak/Desktop/symfony/test/config/routes/../../src/Controller/ (which is being imported from "/Users/peterkosak/Desktop/symfony/test/config/routes/annotations.yaml"). Make sure annotations are installed and enabled.)

    when using without square [


    /**
    * @IsGranted("ROLE_ADMIN","ROLE_MANAGER")
    */


    getting this


    Exception thrown when handling an exception (Symfony\Component\Config\Exception\FileLoaderLoadException: [Syntax Error] Expected Value, got 'ROLE_MANAGER' at position 24 in class App\Controller\ResourcePlanningController in /Users/peterkosak/Desktop/symfony/test/config/routes/../../src/Controller/ (which is being imported from "/Users/peterkosak/Desktop/symfony/test/config/routes/annotations.yaml"). Make sure annotations are installed and enabled.)


  • 2018-09-28 Peter Kosak

    it is screaming about annotation not installed but when I use only 1 role in annotation I will get Access Denied

  • 2018-09-28 weaverryan

    Oh, and I just realized I misread your first comment! IsGranted with multiple roles is NOT working? It should - it should have the same affect as passing denyAccessUnlessGranted() those same 2 roles. What are you seeing?

    Cheers!

  • 2018-09-28 weaverryan

    Hey Peter Kosak!

    Good question! You can use multiple roles *anywhere* in Symfony - the IsGranted() annotation, denyAccessUnlessGranted, and even in access_control I believe. But, I never do this, because, for me, it's not clear what passing 2 roles means. Is it an "OR" (ROLE_ADMIN or ROLE_MANAGER) or an "AND". The answer is "OR", but because it's not clear to look at, I don't prefer using it (https://github.com/symfony/.... Instead, I rely on role_hierarchy - i would probably give ROLE_ADMIN the ROLE_MANAGER role in the hierarchy. But, it depends on your needs - there is certainly nothing wrong with passing multiple roles :).

    > btw ryan you have to update email just saw it in IsGranted.php :)

    What do you mean? What email? :)

    Cheers!

  • 2018-09-28 Peter Kosak

    btw ryan you have to update email just saw it in IsGranted.php :)

  • 2018-09-28 Peter Kosak

    Annotation @IsGranted can I somehow use it on multiple roles?

    I have tried @IsGranted(["ROLE_ADMIN","ROLE_MANAGER"]) but this doesnt work.

    I would like to check if the user has at least 1 of the roles.