Reputation: 1971
I'm working on managing access for users to some pages on my site. I have 1 type of fully authenticated users (role: ROLE_MEMBER
, based on ROLE_USER
) and, of course, anonymous users too.
Let's say I have 2 pages (/index
, /account
) on the site, both with secure: true
. Let's say /index
requires role: IS_AUTHENTICATED_ANONYMOUSLY
and /account
requires role: IS_AUTHENTICATED_FULLY
(for ROLE_MEMBER
).
I want to show special "account menu" for logged in members on both pages, so in template i check is_granted('ROLE_MEMBER')
.
That works great for /account
, of course. The problem, when member is navigated to /index
(which is "anonymous" page) function is_granted('ROLE_MEMBER')
returns 0
, and is_granted('IS_AUTHENTICATED_ANONYMOUSLY')
returns 1
. When members navigates to /account
again, everything works without reentering password (that means member still not logged out).
So, the question is how to detect what member is logged in user inside template for /index
page?
UPDATED.
@alessandro1997 here is my app/config/security.yml
configuration
security:
encoders:
AG\MemberBundle\Entity\Member:
id: member_saltedpassword_encoder
role_hierarchy:
ROLE_MEMBER: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_MEMBER, ROLE_ALLOWED_TO_SWITCH]
providers:
member_db:
entity: { class: AGMemberBundle:Member, property: email }
firewalls:
members:
pattern: ^/account
security: true
form_login:
login_path: /account/login
check_path: /account/login/check
post_only: true
username_parameter: _email
password_parameter: _password
default_target_path: /account/
always_use_default_target_path: true
# csrf token options
csrf_parameter: _csrf_token
intention: authenticate
provider: member_db
logout:
path: /account/logout
target: /
remember_me:
key: "qwewqeqwerwxeweqweqwe"
lifetime: 3600
path: /
domain: ~ # Defaults to the current domain from $_SERVER
pages:
pattern: ^/
security: true
anonymous: ~
access_control:
- { path: ^/account, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Upvotes: 0
Views: 2514
Reputation: 966
It's happening because You are using two separate firewalls and You authenticate user only to one firewall - they are completely separate security systems. You should set up only one firewall and use access_control with diffrent roles signed.
I've had very similar problem - check it out here -> Symfony 2 - firewall and access control issue
Upvotes: 1
Reputation: 966
I think it might be a problem with:
access_control:
- { path: ^/account, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
First you're setting the access to /account, and then you override it with access to index path: / . I think it might be ok if you will swap it. Besides I believe there is no point in using access control for user who is authenticated_annonymously. Use that instead:
access_control:
- { path: ^/account, roles: IS_AUTHENTICATED_FULLY }
Another problem is that login and login_check are hidden behind the firewall - user who will try to log in will not be able to see the login page, as you have set the /account path only for fully authenticated users and now:
form_login:
login_path: /account/login
check_path: /account/login/check
I believe it should work with something like that:
firewalls:
login_firewall:
pattern: ^/account/login$
anonymous: ~
access_control:
- { path: ^/account, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/account/login, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/account/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY}
However, in my app, I just took the login and login_check paths out of the /account, so the security.yml looks like that:
security:
firewalls:
login_firewall:
pattern: ^/login$
anonymous: ~
secured_area:
pattern: ^/
form_login:
login_path: /login
check_path: /login_check
always_use_default_target_path: true
default_target_path: /
logout:
path: /logout
target: /
providers:
main:
entity: { class: Core\UserBundle\Entity\User, property: username }
encoders:
Core\UserBundle\Entity\User:
algorithm: sha256
iterations: 10
encode_as_base64: true
access_control:
- { path: ^/admin, roles: ROLE_SUPERADMIN }
- { path: ^/user, roles: ROLE_USER }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
I'm not a Symfony expert and it might not be the perfect solution, but I hope that helps ;)
Upvotes: 0