I want to show a certain div if the user has ROLE_ADMIN attributed to him. In the database, the user has the roles ROLE_ADMIN and ROLE_USER:
a:1:{i:0;s:10:"ROLE_ADMIN";}
However, when I use the following code, the user is not granted permission and the div is not shown:
{% if is_granted('ROLE_ADMIN') %}
<div class="settings">...</div>
{% endif %}
The div is shown if I use is_granted('ROLE_USER') instead.
A Twig dump shows me that the user indeed has both roles attributed to him.
Any ideas as to why this code doesn't work as expected?
Extra code info:
security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_ADMIN
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
login_path: /login
check_path: /login_check
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
login_path: /login
failure_path: /login
oauth_user_provider:
service: my_user_provider
logout: true
anonymous: true
login:
pattern: ^/login$
security: false
remember_me:
secret: "%env(APP_SECRET)%"
always_remember_me: true
path: /
domain: ~
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 }
The getRoles() functionality is handled via the User entity from FOSUserBundle:
public function getRoles()
{
$roles = $this->roles;
foreach ($this->getGroups() as $group) {
$roles = array_merge($roles, $group->getRoles());
}
// we need to make sure to have at least one role
$roles[] = static::ROLE_DEFAULT;
return array_unique($roles);
}
Related
I'm working on a custom membership website which is based on the Symfony2. This website has two type of the bundles. FOSuserbundle and SamlBundle.
I integrated SamlBundle with FOSuserbundle. Single Sign-On system is working now, but FOSuserbundle login form is not working.
This is my security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface:
id: app.my_password_encoder
PDias\SamlBundle\Security\User\SamlUser: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
backend_samlservice:
id: saml.backend.fosuser.provider
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
require_previous_session: true
login_path: /login
check_path: /login_check
always_use_default_target_path: false
default_target_path: /
use_forward: true
use_referer: false
saml:
provider: backend_samlservice
direct_entry: false
login_path: /login-saml
check_path: /login-check-saml
default_target_path: /
always_use_default_target_path: true
logout:
path: /logout
target: /login
anonymous: true
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
remember_me:
key: '%secret%'
lifetime: 604800 # 1 week
path: /
domain: ~
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/sendemail, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^, role: ROLE_USER }
acl:
connection: default
Even if I was not using Single Sign-On, backend_samlservice will be executed.
When I use ID & Password to login to the website, I will be redirected to the login page.
Do I have to add something?
Thanks for your anwsers.
I've fixed this problem.
The point was SimpleSAML_Session. I had to clean up the session like this.
https://simplesamlphp.org/docs/stable/simplesamlphp-sp#section_6
$session = SimpleSAML_Session::getSessionFromRequest();
$session->cleanup();
I added this code on the SamlAuth.php(pdias/saml-bundle/PDias/SamlBundle/Saml). Then it started working.
I have a knowledge problem I guess.
I thought, secure an area is done by the firewall. So for my understanding, I only have to write the area down inside the "access_control" to secure it by roles, isn't iT?
Actually, my security.yml looks like:
security:
encoders:
FOS\UserBundle\Model\UserInterface: pbkdf2
role_hierarchy:
ROLE_USER: [ROLE_USER]
ROLE_MODERATOR: [ROLE_AUTHOR]
ROLE_ADMIN: [ROLE_MODERATOR]
ROLE_SUPER_ADMIN: [ROLE_ADMIN]
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
# restrict the firewall to specific http methods
methods: [GET, POST]
access_denied_url: /error403
form_login:
check_path: /login_check
# the user is redirected here when they need to log in
login_path: /login
# if true, forward the user to the login form instead of redirecting
use_forward: true
# login success redirecting options (read further below)
always_use_default_target_path: false
default_target_path: /de/dashboard/
target_path_parameter: _target_path
use_referer: false
provider: fos_userbundle
csrf_provider: form.csrf_provider
default_target_path: /login
logout: true
anonymous: true
logout:
path: /logout
target: /login
invalidate_session: false
delete_cookies:
a: { path: null, domain: null }
b: { path: null, domain: null }
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user, role: ROLE_ADMIN }
- { path: ^/administration, role: ROLE_ADMIN }
But if I login with a "ROLE_USER" account, I can access the "administration path anyway.
Where is my problem? Do I miss somenthing? Do I need a listener or something or will this be handled automatically?
Unable to find the login_check in symfony2.0 (I know it should be symfony2.4 because it is decrypted, but my customer wants 2.0).
What is wrong that symfony cannot finde the login_check-path?
My routing.yml:
backend_account_login:
pattern: /{_locale}/secured/login
defaults: { _controller: BackendAccountBundle:Secured:login }
requirements:
_locale: en|de
security_check:
pattern: /{_locale}/secured/login_check
requirements:
_locale: en|de
logout:
pattern: /de/secured/logout
defaults: { _controller: BackendAccountBundle:Secured:logout }
My security.yml:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
#Use of an encoder Backend\AccoundBundle\Services
Backend\AccountBundle\Entity\User:
id: sha256salted_encoder
role_hierarchy:
ROLE_ADMIN: ROLE_AHA_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
#two providers are given. the aha users from the db and the admin.
#admin still have an unsecured password
providers:
chain_provider:
providers: [in_memory, user_db]
in_memory:
users:
admin: { password: 2, roles: ROLE_ADMIN }
#for aha-users there is a custom table. the login procedure is getting the data from the entity
user_db:
entity: { class: Backend\AccountBundle\Entity\User, property: email }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/(en|de)/secured/login
#security: false
anonymous: ~
secured_area:
pattern: ^/(en|de)/secured/
anonymous: ~
http_basic:
realm: "Secured Area"
form_login:
check_path: security_check
login_path: backend_account_login
use_referer: false
default_target_path: backend_secured_account_index
#target_path_parameter: frontend_account_my_account
logout:
path: /de/secured/logout
target: /de/
#default_target_path: frontend_account_login
#anonymous: ~
#the access of user e.g. admin and aha users are given below
access_control:
- { path: ^/*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/secured/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/secured/, roles: [ROLE_AHA_USER, ROLE_ADMIN] }
- { path: ^/(en|de)/secured/account/admin/register/, roles: ROLE_ADMIN }
As suggested by 2.0.25 Symfony Dependency Injection and the doc reference (found below) you should define your check_path as an absolute url and not a route name. (e.g.: /en/secured/login_check)
Security reference for 2.0 (deprecated):
http://symfony.com/doc/2.0/reference/configuration/security.html#the-login-form-and-process
Current:
http://symfony.com/doc/current/reference/configuration/security.html#the-login-form-and-process
(This latter states that you may use route name. )
My entire webpage has to be private with only authenticated users accepted. I'm using FOSUserBundle and have this as setting:
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
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 }
When I set anonymous as false or get rid of it, I get a "problem loading page" error where the page will just crash. Also, when anonymous is true, when I login with the right credentials it logs me in but does not redirect to the main index page, instead it stays on /login and gives me "Logged in as user | Logout".
So the behavior I need it to be is:
1) On homepage, it will redirect to /login page if user is not authenticated (no anonymous users)
2) After login authenticated, redirects to homepage
It is all done in firewall settings
1) add firewall rule:
access_control:
- { path: ^/$, role: ROLE_USER }
2) add default_target_path:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
default_target_path: /
i have a Twig extension menu in my page, but i need use isGranted method to display the menu items according to the user, but symfony2 profilers shows me an alert:
The profilers says:
AuthenticationCredentialsNotFoundException: The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.
in C:\xampp\htdocs\galvez_motos\app\cache\dev\classes.php line 2395
at SecurityContext->isGranted('ROLE_ADMIN') in C:\xampp\htdocs\galvez_motos\src\GalvezMotos\AlmacenBundle\Twig\MenuExtension.php line 432
How can i use the isGranted method before login?
security.yml:
security:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login_check
logout:
path: /logout
target: /
invalidate_session: false
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: ROLE_USER }
providers:
user_db:
entity: { class: GalvezMotos\AlmacenBundle\Entity\Usuario, property: username }
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
encoders:
GalvezMotos\AlmacenBundle\Entity\Usuario:
algorithm: sha1
iterations: 1
encode_as_base64: false
Pd: Images