3
votes

I'm using two firewalls with same pattern for two types of users:

  • Admin with access to both frontend and backend who can see some extra controls in frontend app then normal user.
  • User who can access only frontend.

This is my simplified security.yml configuration:

firewalls:
    admin:
        pattern: .*
        form_login:
            login_path: /admin/login
            check_path: /admin/login
        logout:
            path:   /admin/logout
        ...

    front:
        pattern: .*
        form_login:
            login_path: /user/login
            check_path: /user/login-check
        logout: true
        anonymous: true
        ...

    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false


access_control:
    - { path: ^/admin/, role: ROLE_ADMIN }
    - { path: ^/admin/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/user/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/user/profile, role: ROLE_FRONTEND_USER }
    - { path: ^/user/upload-photo, role: ROLE_FRONTEND_USER }
    ...

The problem is that when any non loggedin user tries to access for example /user/profile they're redirected to /admin/login. I Guess this is because there's no connection between firewall and access_control so Symfony can't know if the user tried to access section for ROLE_FRONTEND_USER or ROLE_ADMIN and then redirected accordingly.

My question is, is there any elegant way to solve this? Maybe use an event listener and manually check on denied permissions whether the requested URL required ROLE_FRONTEND_USER or ROLE_ADMIN roles?

1
Don't be surprised when you have all the same patterns, and the first matched pattern win. It is the same like routes. Your first firewall shoul be restricted to pattern: ^/admin, if not match then second firewall match and user will be redirected to user/login. Cheers. - malcolm
I can match only ^/admin for reasons explained in the question. - martin

1 Answers

0
votes

You can manually set the url where the user will be redirected :

front:
    pattern: .*
    # ...
    access_denied_url: /user/login

Anonymous users will be redirected to the expected login route without need of a specific pattern per firewall.

Hope this solves your problem.