I am having issues securing a route 'dashboard' to a custom user role. I am using FOSUserBundle and I am aware that due to due users are given ROLE_USER by default - even though this role does appear in the user table.
On a user sign in (this happens via Steam) I add a new custom
$user->setRoles(['ROLE_LOGGED_STEAM_USER']);
My issue flows as such - User hits site - User logs in - redirect to Dashboard route - with the access denied error.
I have also disabled the security line and dumping out the ROLES to which I can pull from the token user object to confirm the ROLE exists and matches the rule
Here is my security ACL
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
steamauth:
id: steam.user_provider
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
provider: steamauth
pattern: ^/
form_login:
provider: fos_userbundle
logout: true
anonymous: true
form_login:
login_path: login
check_path: login_check
steam:
default_route: controller.dashboard.home
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/dashboard, role: ROLE_LOGGED_STEAM_USER }
Initially, I wasn't aware that all roles had to Begin with ROLE_*
Here is a screenshot of the user entry with the role attached here
I hope its somthing simple im just overlooked so any help would be great!
Thanks it advance for any help/suggestions!
Not sure but I think you have a typo, please try changing role to roleS wtih "s"
- { path: ^/dashboard, roles: ROLE_LOGGED_STEAM_USER }
I think you must register your custom role on the "role_hierarchy" so the code will be:
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_LOGGED_STEAM_USER]
ROLE_SUPER_ADMIN: ROLE_ADMIN
Hope it help.
Related
I have a Symfony 3 CRM with FOS User Bundle installed for the login. The issue is, most users of this CRM will be engineers belonging to a company who are only allowed to see certain parts, so I have created their own dashboard specifically. Admin users can see everything and simply redirect to the main dashboard. However, it seems that only users with ROLE_ADMIN are allowed to access the CRM and everyone else is denied regardless of where they go.
Here is my security file:
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_STAFF: ROLE_USER
ROLE_ADMIN: ROLE_STAFF
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
# if you are using Symfony < 2.8, use the following config instead:
# csrf_provider: form.csrf_provider
use_referer: false
success_handler: login_success_handler
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: ROLE_ADMIN }
- { path: ^/staff-dashboard, role: ROLE_STAFF }
As you can see I have created a custom role called ROLE_STAFF which is assigned to engineers (or staff members) and they are allowed to view the staff-dashboard link. I have a test user with the ROLE_STAFF role but I still am unable to view staff-dashboard.
I also have the following if statement in my controller, so it redirects all those users who are NOT admin to the staff-dashboard:
if($userRole === "ROLE_ADMIN") {
return $this->render('AppBundle:pages:dashboard.html.twig', array(
'latest' => $latest,
'cashflow_chart' => $ob,
'job_chart' => $ob2
));
} else {
return $this->redirectToRoute('app_staff_dashboard');
}
But again, this does not work.
Any help with this is appreciated - I haven't yet found a solid solution.
Access control rules are processed in order specified in config. First matched rule (matched path) is checked and processing stops.
For your case 2 rules match path /staff-dashboard: 1 - { path: ^/, role: ROLE_ADMIN } and 2 - { path: ^/staff-dashboard, role: ROLE_STAFF }. The 1-st one is checked. Staff users don't pass this rule.
Change the order of these 2 rules.
I am using Symfony 3.2 and fos user bundle 2.0
I use the classic setup : "Getting Started With FOSUserBundle"
security:
always_authenticate_before_granting: true
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_CLIENT
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
logout: true
anonymous: ~
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, role: ROLE_ADMIN }
- { path: ^/client, role: ROLE_CLIENT }
It work but something is strange :
When I logout and navigate to public page it appears as I am always logged
I need to manually reload the page in my browser to make the logout effective.
( I use the {% if is_granted('ROLE_ADMIN') %} in my template )
Is it a problem with my security configuration or a problem with cache memory?
Some help will bee appreciated
thank
Vincent
Try adding the ROLE_USER to your role hierarchy like this:
role_hierarchy:
ROLE_CLIENT: ROLE_USER
ROLE_ADMIN: ROLE_CLIENT
As stated in the docs: "Make sure every user has at least one role, or your user will look like they're not authenticated. A common convention is to give every user ROLE_USER." http://symfony.com/doc/current/security.html#roles
today I have noticed I can always access the register and reset form regardless if I am authenticated or not.
Here is my security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout:
delete_cookies:
activeGame: {}
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
Regarding http://symfony.com/doc/current/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources it seems "normal" to be able to access this pages.
But how can I "easily" disable it for authenticated user or did I miss anything?
Thanks in advance!
You may be able to accomplish what you are looking for by using the newly introduced allow_if expression for access controls.
- { path: ^/register, allow_if: "not is_authenticated()" }
Another way may be:
- { path: ^/register, allow_if: "user == 'anon'" }
I havent fully tested this but it should only allow users who are not authenticated fully or authenticated remembered to access that path
Here is a little bit about the security
Here are some of the variable and functions available in expressions
Then here is some info on the Expressions you can use in allow_if
IF however, you do not want to throw a 403 Access Denied Exception when logged in users try and access those pages. Instead you would like to redirect them elsewhere then you can add a check to their respective controller actions. Something like:
public function registerAction()
{
if (true === $this->get('security.context')->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return $this->redirect($this->generateUrl('some_route_to_send_them_to'));
}
// ...
}
I have installed FOSUserBundle, I see that's active and my login page is ok too. The problem comes out when I try to login as an user. If I insert wrong credentials, nothing happens, I'm redirected to the login page without signalling "bad credentials" as usual. If I insert right user information, I'm redirected to the homepage and I'm not logged in, in the Symfony toolbar I'm authenticated as anonymous and I have only an AnonymousToken.
This is my security.yml:
security:
encoders:
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
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
check_path: fos_user_security_check
csrf_provider: form.csrf_provider
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
This is part of my config.yml:
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: ***\***Bundle\Entity\User
In Symfony log, I can read:
security.INFO: User "sampleuser" has been authenticated successfully [] []
but this is apparently not happening.
I've just found the solution to my problem. The cause was LswMemcacheBundle ,
I have installed memcached php extension, but i haven't run memcache on my system. I've run it and afterwards all login/logout functionalities have started working correctly.
I've been using FOSUserBundle for a long time now, but this never happened to me. It seems that the firewall is not working, because I can access any page from my site, when I should only be redirected to the login page when accessing as ANONYMOUS.
So, this is my security file:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js|assets)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout:
invalidate_session: false
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: ROLE_USER }
And this is my config.yml file:
#v1.0
imports:
- { resource: parameters.yml }
- { resource: security.yml }
fos_user:
db_driver: orm
firewall_name: main
user_class: My\Bundle\Entity\User
So, from where I see, everything is configured correctly so It should work as expected. But, this is not happening. So, the questions is: where else should I look for any conflictive configuration file, or conflictive entities, etc? Because I've been debugging for hours before coming to ask the question here (I did not want to ask a silly question), but I cannot figure out what could be happening.
Any ideas?
your problem:
The correct ACL attribute is roles not role.
working examples:
security:
# ...
access_control:
# ...
- { path: ^/, roles: ROLE_USER }
- { path: ^/admin, roles: [ROLE_ADMIN, ROLE_TRANSLATOR] }
explanation:
Because of the wrong attribute name there are effectively no mandatory roles configured.
That's why - as you have anonymous set to true - access will currently be granted without any restrictions.
Please have a look at the documentation chapter Securing specific URL patterns.