snakeoil snakeoil - 9 months ago 85
PHP Question

Symfony security / access_control, lots of redundant entries

entries and each is a combination of:

  • a URL pattern

  • a host name pattern

  • channel requirement (http, https)

  • roles requirements

My understanding is Symfony only matches ONE per request, but this is also the highest-level place to enforce HTTPS.

So then, does this mean a duplicate rule for each unique URL pattern / role requirement?

  • # rules..

  • a rule for /admin requiring ROLE_ADMIN for localhost

  • a rule for /admin requiring ROLE_ADMIN, forcing https

  • a rule for /api requiring ROLE_API for localhost

  • a rule for /api requiring ROLE_API, forcing https

  • a rule for / allowing anonymous for localhost

  • a rule for / allowing anonymous, forcing https

  • # more rules..


You're right, for each incoming request, Symfony will decide which access_control to use based on the URI, the client's IP address, the incoming "HOST NAME"!, and the request method.

But for your happiness there a way to not duplicate the rules and achieve the same goal.

"The Special parameters.yml File"

It defines the values that usually change on each server.

First, in your local development machine, define a new parameter into app/config/parameters.yml file, let's named "requires_channel":

# in your local development machine (development)
    database_driver: pdo_mysql
    # ...
    requires_channel: http  # <- Wow! I can use this var anywhere into my configuration :)

do the same on production server, but setting https:

# in your deployment server (production)
# app/config/parameters.yml
    database_driver: pdo_mysql
    # ...
    requires_channel: https # <- I need enforce https redirection now in production server

Now, you can to define only one rule per entry and use your new %requires_channel% parameter:

# app/config/security.yml
    # ...

        - { path: ^/admin, role: ROLE_ADMIN, requires_channel: '%requires_channel%' }
        # ...

%requires_channel%: its value depends on host where running your application.

Note that host attribute is not important anymore, because it was needed to differentiate both rules before.

This solution could be done by using environments config files (config_dev.yml and config_prod.yml), but probably you need test your application for prod environment too in localhost (http).

I hope I've helped!