Search code examples
phpsymfonysymfony-security

Symfony access control with variable inside route


I'm defining security for my website in security.yml

    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/ad/new, role: ROLE_USER  }
    - { path: ^/myAds, role: ROLE_USER  }
    - { path: ^/payments, role: ROLE_USER  }
    - { path: ^/pay, role: ROLE_USER  }

But I'm not sure how such a route would be added here:

mybundle_contact_advertiser:
   path:    /ad/{id}/contact
   defaults:   { _controller: MyBundle:Default:contactAdvertiser,id:null}

How is the id defined, considering I can't do it like so:

    - { path: ^/ad, role: ROLE_USER  }

As a route like

mybundle_ad:
    path:      /ad/{id}
    defaults:  { _controller: MyBundle:Default:viewAd ,id:null}

Would not work for unregistered users.


Solution

  • I have two solutions for you.

    First, add prefix to routes which need authentication and authorization. Then simply add that that prefix to your security.yml file. This way you do not need to add all routes manually.

    Second, change your route to:

    mybundle_contact_advertiser:
       path:    /ad/contact/{id}
       defaults:   { _controller: MyBundle:Default:contactAdvertiser}
    

    Then add the following to your security.yml file:

    - { path: ^/ad/contact/, role: ROLE_USER  }
    

    But, if you do not want to change the route then check authorization inside your action

     $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
    

    Or

    if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
        throw $this->createAccessDeniedException();
    }
    

    Last but not least, you can use @Security annotation to secure your actions.

    /**
     * @Security("has_role('ROLE_USER')")
     */