问题
Question: I want to create an admin part in my Symfony2 website that would be available only to users with a ROLE_ADMIN
I don't know if I should create a new firewall or use acces controls. I tried to do both together but the admin part is still accessible to all users.
Currently all the website is under secured area firewall and pages i want available to anonymous are freed with access control.
Here is my security.yml
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
my_facebook_provider:
id: my_user.facebook_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
context: login
admin:
pattern: /admin/
form_login:
provider: fos_userbundle
check_path: /login_check
login_path: /login
anonymous: ~
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: /login
check_path: /login_check
default_target_path: tk_group_homepage
provider: fos_userbundle
remember_me: true
csrf_provider: form.csrf_provider
remember_me:
key: %secret%
lifetime: 31536000 # 365 days in seconds
fos_facebook:
app_url: "%api_facebook_name%"
server_url: "%api_facebook_server%"
check_path: /login_facebook_check
default_target_path: tk_user_homepage
provider: my_facebook_provider
logout:
path: fos_user_security_logout
target: fos_user_security_login
invalidate_session: false
context: login
access_control:
- { path: ^/$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/new, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/invitation, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(subscribe|about|blog|press|contact), role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/admin/, role: ROLE_ADMIN }
I am also thinking about checking in the controller is the user has an admin role and throwing an exception if not, as my admin part is only one page currently. But I do not know if it is best practice and it could be a problem if i want to extend my admin part.
And I do not want to create a new user provider as we would be only 2 admins.
Thank you very much, Jules
回答1:
You should remove the admin firewall and rely on access_control; If you have admin login form under the /admin/ URL, you of course will not be able to see it before logging in, so you should either use the /login form to sign in as admin, or modify your access_control:
- { path: ^/admin/login/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
here is what official doc says about your situation:
- Multiple firewalls don't share security context If you're using multiple firewalls and you authenticate against one firewall, you will not be authenticated against any other firewalls automatically. Different firewalls are like different security systems. To do this you have to explicitly specify the same Firewall Context for different firewalls. But usually for most applications, having one main firewall is enough.
http://symfony.com/doc/current/book/security.html#book-security-common-pitfalls
You should read the whole Common pitfalls section
If you would really really like to use different firewalls, just do as the documentation states, and share the same firewall context beetween them. This is also described in the documentation: http://symfony.com/doc/current/reference/configuration/security.html#reference-security-firewall-context
and here is a simple example:
admin:
(... other options ...)
context: my_security_context
secured_area:
context: my_security_context
(... other options ...)
回答2:
The Access Control looks for the first match.
Because of that you need to put this line:
- { path: ^/admin/, role: ROLE_ADMIN }
Before this line:
- { path: ^/$, role: IS_AUTHENTICATED_ANONYMOUSLY }
If you do not, /admin/whatever matches the path ^/$ and needs no ROLE_ADMIN.
来源:https://stackoverflow.com/questions/19082053/symfony2-2-firewalls-1-login