I have 3 roles in my project:
admin=> /admin
customer=> /customer
therapist=> /therapist
I config the security firewalls and work correctly.
But I need to know customer user is logged in or therapist user form outside of secured area.
Is there any way to config firewall to access shared secured area?
If I change the pattern of customer and therapist to / , the customer firewall wont work.
this is my security.yml
security:
encoders:
Utab\AdminBundle\Entity\User:
algorithm: bcrypt
Arg\TherapistBundle\Entity\User:
algorithm: bcrypt
Shop\CustomerBundle\Entity\User:
algorithm: bcrypt
providers:
admin_provider:
entity:
class: 'UtabAdminBundle:User'
therapist_provider:
entity:
class: 'ArgTherapistBundle:User'
shop_customer_provider:
entity:
class: 'ShopCustomerBundle:User'
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_firewall:
pattern: /admin/.*
simple_form:
provider: admin_provider
check_path: admin_login_check
login_path: admin_login
failure_path: admin_login
default_target_path: admin_profile
authenticator: google_recaptcha_authenticator
failure_forward: true
logout:
path: admin_logout
target: admin_login
anonymous: true
therapist_firewall:
pattern: /therapist/.*
simple_form:
provider: therapist_provider
check_path: therapist_login_check
login_path: therapist_login
failure_path: therapist_login
default_target_path: therapist_profile
authenticator: google_recaptcha_authenticator
logout:
path: therapist_logout
target: /
anonymous: true
shop_customer_firewall:
pattern: /customer/.*
simple_form:
provider: shop_customer_provider
check_path: shop_customer_login_check
login_path: shop_customer_login
failure_path: shop_customer_login
default_target_path: shop_customer_profile
authenticator: google_recaptcha_authenticator
logout:
path: shop_customer_logout
target: shop_customer_login
anonymous: true
access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/therapist/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/therapist/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/therapist/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/therapist/, role: ROLE_THERAPIST }
- { path: ^/customer/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/customer/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/customer/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/customer/, role: ROLE_SHOP_CUSTOMER }
You can only access the current logged in user (and his roles) in the current firewall. If no firewall is defined for the current URL, you cannot access the data.
However, there is a solution. Make one large firewall with the three current firewalls combined. Then, use Access Control to restrict access to sub-URLs. You should definitely think about the different User entities you are using now.
Example:
# app/config/security.yml
security:
# ...
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/customer, roles: ROLE_CUSTOMER }
- { path: ^/therapist, roles: ROLE_THERAPIST }
Also read the documentation.
Related
I have a problem with creation anonymous route in my project. I have almost all bundle protected but some routes I need to make accessible externally. I tried many hours how it should be but seems that I am missing something. I am attaching config files.
Config.yml
security:
access_decision_manager:
strategy: consensus
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
AppBundle\Domain\Customer\Customer: bcrypt
role_hierarchy:
ROLE_CUSTOMER: ROLE_USER
ROLE_CUSTOMER_CONFIRMED: ROLE_CUSTOMER
ROLE_ACCOUNT: ROLE_USER
ROLE_ADMIN: ROLE_ACCOUNT
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username
customer:
id: app.customer.user_provider
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_customers_login:
pattern: ^/api/customers/login
anonymous: true
api_login:
pattern: ^/api/login
stateless: true
anonymous: true
form_login:
provider: customer
check_path: /api/login
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
api:
provider: customer
# pattern: ^/api(?!/doc|/conventions/*|/speakers/*|/events/*|/workshops/*|/agendadays/*)
pattern: ^/api(?!/doc|/public/*)
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
# - app.customer.jwt_token_authenticator
shop:
provider: customer
pattern: ^/shop
form_login:
provider: customer
csrf_token_generator: security.csrf.token_manager
use_referer: true
login_path: shop_login
check_path: shop_login_check
# check_path: shop_login
always_use_default_target_path: true
default_target_path: shop_default_index
logout:
path: shop_logout
target: shop_default_index
# handlers: [user.logout_handler]
anonymous: true
remember_me:
secret: '%secret%'
# lifetime: 86400 # 1 day
lifetime: 3600 # 1 day
path: /shop
name: shop_remember
main:
provider: fos_userbundle
pattern: ^/(?!/api)
# #deprecated
entry_point: user.entry_point
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
use_referer: true
login_path: fos_user_security_login
check_path: fos_user_security_check
always_use_default_target_path: false
default_target_path: homepage
logout:
path: fos_user_security_logout
target: homepage
handlers: [user.logout_handler]
anonymous: true
switch_user: true
remember_me:
secret: '%secret%'
lifetime: 3600 # 1 day
path: /
name: main_remember
access_control:
- { path: ^/[0-9]+/agenda/feed.xml, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/customers/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/public, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/doc, roles: [ROLE_ADMIN, ROLE_ACCOUNT] }
- { path: ^/shop/.+/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/shop/.+/customer/email-confirm, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/shop/.+/customer, roles: ROLE_CUSTOMER }
- { path: ^/shop/.+/cart/checkout, roles: ROLE_CUSTOMER_CONFIRMED }
- { path: ^/shop/.+/cart, roles: ROLE_CUSTOMER }
- { path: ^/shop, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/presence/check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/users/current, roles: [ROLE_ADMIN] }
- { path: ^/users, roles: [ROLE_SUPER_ADMIN] }
- { path: ^/action-log, roles: [ROLE_SUPER_ADMIN] }
- { path: ^/, roles: [ROLE_ADMIN, ROLE_ACCOUNT] }
In controller action is defined like:
/**
*
* #Route("/{convention}/agenda/feed.xml", name="convention_agenda_feed")
* #param Request $request
* #param Convention $convention
* #return Response
* #throws \InvalidArgumentException
*/
public function agendaFeedAction(Request $request, Convention $convention): Response
{
There are no other annotations on controller.
I need to access page like 'localhost/22/agenda/feed.xml' without logging in, but now when I open that page I am redirected immediatelly yo login page.
Bceause this statement matches all routes:
{ path: ^/, roles: [ROLE_ADMIN, ROLE_ACCOUNT] } and for all routes you need ROLE_ADMIN or ROLE_ACCOUNT, you need to be more specific to avoid this. Something like ^/api that you have.
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.
As the title suggests, I'm going to use Facebook,Google and GitHub authentication alongside JWT authenticator (LexikJWT).
Before starting, I want to know how can I use them? is it possible to use both of them to protect APIs?
If yes, what sort of configurations should my security have? Assuming that I'm using the default configurations.
here is the current security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
acl:
connection: default
access_decision_manager:
strategy: affirmative
role_hierarchy:
ROLE_SALES_NOTIFICATIONS: [ ROLE_SALES_NOTIFICATIONS ]
# FULL CONTROL
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
# Disabling the security for the web debug toolbar, the profiler and Assetic.
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# -> custom firewall for the admin area of the URL
admin:
pattern: /admin(.*)
context: user
form_login:
provider: fos_userbundle
login_path: /admin/login
use_forward: false
check_path: /admin/login_check
failure_path: null
success_handler: admin_success_handler
logout:
path: /admin/logout
anonymous: true
# Custom firewall for api area
api_login:
pattern: ^/api/auth
stateless: true
anonymous: true
provider: fos_userbundle
form_login:
check_path: /api/auth/check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
api:
pattern: ^/api/v\d+\.\d+/
methods: [ POST, PUT ]
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
api_doc:
pattern: ^/api/doc
stateless: true
anonymous: true
# -> end custom configuration
# default login area for standard users
# This firewall is used to handle the public login area
# This part is handled by the FOS User Bundle
main:
pattern: .*
context: user
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: /login_check
failure_path: null
logout: true
anonymous: true
access_control:
# URL of FOSUserBundle which need to be available to anonymous users
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Admin login page needs to be access without credential
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
- { path: ^/assets/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/uploads/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
- { path: ^/user/, role: [ROLE_USER] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/auth/me, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/v\d+\.\d+/, roles: IS_AUTHENTICATED_FULLY }
I'm thinking, using both of them as a security provider will lead to errors. is it right?
I don't think using HWIOAuthBundle and LexikJWTBundle on the same project will lead to errors.
You api_login firewall will authenticate your api users while your admin firewall will authenticate your backoffice users.
Since your URL patterns are correctly congigured you should not encounter problems.
I am using SonataAdmin bundle in conjunction with SonataUser Bundle for admin area management and authentication.
However, I desire non-admin users to be registered at the from the frontend and sign-up to make order requests.
I am having an issue authenticating users from the frontend, I keep getting a bad credentials error.
I am using
FOSUserBundle: ~2.0#dev
SonataUserBundle: dev-add_support_for_fos_user2
Here's my security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
SONATA:
- ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT
providers:
fos_userbundle:
id: fos_user.user_manager
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin:
pattern: /admin(.*)
context: user
form_login:
provider: fos_userbundle
login_path: /admin/login
use_forward: false
check_path: /admin/login_check
failure_path: null
logout:
path: /admin/logout
target: /admin/login
anonymous: true
main:
pattern: .*
context: user
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: fos_user_security_check
failure_path: null
success_handler: authentication_handler
failure_handler: authentication_handler
require_previous_session: false
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Admin login page needs to be accessed without credential
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
acl:
connection: default
I'm trying to share the user's session between the frontend and the backend. For example, if you access to domain.com/login and you login succesfully, you should be able to access (if you have enough privileges) to domain.com/admin/, without a new login. The other way is, if you access to domain.com/admin/login and sign in succesfully, when you go to domain.com/, you should be already identified, without a new login action.
So, the question is, how can I share the login for the same domain?
My security.yml:
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
admin:
pattern: /admin(.*)
form_login:
provider: fos_userbundle
login_path: admin_login
check_path: admin_login_check
default_target_path: admin_home
logout:
path: admin_logout
target: admin_login
anonymous: true
security: true
context: application
remember_me:
key: XXXXXXXXXXXX
lifetime: 86400
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
security: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
And my config.yml
session:
handler_id: ~
cookie_path: /
name: __XXXXXXX
PD: I'm using the FOSUserBundle.
Setting context to "application" on your main firewall should work (documentation). E.g.
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
security: true
context: application