Symfony 5 security.yaml firewalls pattern rewrites routes - authentication

I am trying to login the user with two different authenticators.
The first authenticator is PatientAuthenticator and the second authenticator is LoginAuthenticator. And i want every route which starts with "/patient" ,to be used PatientAuthenticator and user to be redirected to path "patient.login" and if route start with "/admin" to be used LoginAuthenticator and user to be redirected to "app.login".
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
patient:
pattern: ^/patient/
guard:
authenticators:
- App\Security\PatientAuthenticator
logout:
path: app_logout
admin:
pattern: ^/admin
guard:
authenticators:
- App\Security\LoginAuthenticator
logout:
# The route name the user can go to in order to logout
path: app_logout
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/patient, roles: ROLE_PATIENT }
And the problem is that when in admin firewall i type pattern by this way and the user login , it redirects me again to the login page.
But if i remove ^/admin from pattern and set it to ^/ ,it logs me to the admin but ,when i want to login patient it first send me to admin login route and then it sends me to patient login route.
Does someone know how to fix the regex ?
Thank you :)

Related

Token not found when redirect user based on Roles

I have this security.yml file:
...
security:
encoders:
Trainme\RestBundle\Document\User:
id: security.encoder.blowfish
role_hierarchy:
ROLE_TRAINER: ROLE_USER
ROLE_ADMIN: ROLE_TRAINER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
trainme_admin_provider:
id: trainme_admin.user_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_admin:
pattern: ^/admin
form_login:
check_path: trainme_security_check
login_path: trainme_login
default_target_path: trainme_dashboard
logout:
path: trainme_logout
target: trainme_redirect_route
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/profile, roles: ROLE_TRAINER }
And when user's role is ROLE_TRAINER they will be redirected to /profile, if ROLE_ADMIN then /admin. I do this using the following solution How to redirect to different url based on roles in symfony 2.
The problem is:
When a look at debug toolbar in /profile, it says that i'm not authenticated. Why i'm not authenticated? I already login using login form. But when I logged in as ROLE_ADMIN and i'm in /admin, it says that I'm authenticated.
The authentication process is only triggered if the requested url is behind a firewall. Your firewall is only in place for the pattern ^/admin. If you want the firewall to be active across the whole site you should set your pattern to just ^/ and use the access controls section to define the specific roles for different areas of the site (as you have done). Alternatively you can set up a second firewall if you wish but typically one firewall with appropriate access controls is sufficient.

Sitewide http auth interfering with Symfony2 app authentication

I have a site under development with the following structure:
public_html/
index.php
symfony_app/
other_app/
Currently I have the root of the site behind Basic HTTP authentication during the development testing phase. I couldn't figure out why my Symfony2 authentication for a valid user (myusername) was always redirecting to the Symfony login page. In the logs after successful Symfony login
security.INFO: User "myusername" has been authenticated successfully [] []
I found:
security.INFO: Basic Authentication Authorization header found for user "otherusername" [] []
..which is the user required by .htpasswd in the root of the site. So it seems that I have an issue with, for lack of a better term, nested http authentication.
Is it possible to have a Symfony app living behind http auth without the two clashing?
Security.yml
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
My\UserBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
providers:
administrators:
entity: { class: MyUserBundle:User }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
secured_area:
pattern: ^/
http_basic: ~
form_login:
login_path: login
check_path: login_check
always_use_default_target_path: true
logout:
path: /logout
switch_user: true
access_control:
- { path: ^/, roles: ROLE_USER, requires_channel: https }

Authenticate multiple symfony2 firewalls

I'm trying to authenticate users from in_memory provider for one section on the site and sso provider for all the other pages, so I tried the following:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
sso:
id: sso.security.user.provider
fos_twitter:
id: fos_twitter.auth
in_memory:
users:
ryan: { password: ryanpass, roles: 'ROLE_CANVAS_ADMIN' }
admin: { password: kitten, roles: 'ROLE_CANVAS_ADMIN' }
firewalls:
main:
pattern: ^/canvas
provider: in_memory
secured_area:
pattern: ^/
form_login:
login_path: /signin
check_path: /login_check
anonymous: true
sso: true
fos_twitter: false
access_control:
- { path: ^/canvas, roles: [ROLE_CANVAS_ADMIN] }
This is not working, because it always enter to the /signin login path and this working using the sso provider.
I already tried the following implementations:
Authenticate multiple symfony2 firewalls with one login form,
http://symfony.com/doc/2.0/cookbook/security/custom_authentication_provider.html
and this: http://symfony.com/doc/current/book/security.html#using-multiple-user-providers
None of them work for me.
Can someone help with that?
Thanks..

Symfony2: login does not work on first try after clearing cookies

When trying to log in, Symfony2 tells me that I provided the wrong credentials. Second try works. Any ideas why this could happen?
To reproduce the behaviour, I have to logout, clear cookies, go to the login page again and log in again.
I am using FOSUserBundle.
config.yml:
framework:
#esi: ~
secret: asdfsadfasdf
#translator: { fallback: en }
charset: UTF-8
router: { resource: "%kernel.root_dir%/config/routing.yml" }
form: true
csrf_protection: true
validation: { enable_annotations: true }
templating: { engines: ['twig'], assets_version: v1.2 } #assets_version: SomeVersionScheme
translator: { fallback: de }
session:
default_locale: de
auto_start: false
lifetime: 1000000
...
security.yml:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_manager
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
public:
pattern: ^/.*
form_login:
provider: fos_userbundle
check_path: /login_check
remember_me: true
remember_me:
key: aaasfasdfasdfsadfsadf
lifetime: 1296000 #15 days in second
path: /
anonymous: true
logout: true
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY}
#- { path: ^/_internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
- { path: ^/events/create, roles: ROLE_USER }
#...
acl:
connection: default
routing.yml:
_imagine:
resource: .
type: imagine
_index:
resource: "#AjadoEventHubBundle/Controller/IndexController.php"
type: annotation
fos_comment_api:
type: rest
resource: "#FOSCommentBundle/Resources/config/routing.yml"
prefix: /api
fos_user_security:
resource: "#FOSUserBundle/Resources/config/routing/security.xml"
...
#FOSUserBundle/Resources/config/routing/security.xml:
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_security_login" pattern="/login">
<default key="_controller">FOSUserBundle:Security:login</default>
</route>
<route id="fos_user_security_check" pattern="/login_check">
<default key="_controller">FOSUserBundle:Security:check</default>
</route>
<route id="fos_user_security_logout" pattern="/logout">
<default key="_controller">FOSUserBundle:Security:logout</default>
</route>
</routes>
On my opinion, this is expected behaviour as you enabled anonymous authentication :
You request your app url, without being logged => a session cookie is created with your session ID
An anonymous token is created
You clear cookie => no more session id to identify you
Next request, no token is attached to your login request...
I'm not familiar with symfony, however, I have experienced the same problem when the authentication check looked for a valid cookie, but the cookie was being created after the check--thus causing it to pass the second time, never the first.
By default Symfony require that a session must be exist before the submitting of the form
from the docs
# by default, a session must exist before submitting an authentication request
# if false, then Request::hasPreviousSession is not called during authentication
# new in Symfony 2.3
In order to over come this you could set "require_previous_session" (which is by default true) to false in the "security.yml" as under "form_login" like this:
require_previous_session: false
You could read more about it in Symfony docs in the following link
SecurityBundle Configuration ("security")
I had this problem and I solved it following the answer here Symfony 2 “Your session has timed out or you have disabled cookies”.
#AlterPHP was right, you have to login twice because the first time you are getting an error like this:
Authentication request failed. (...) Your session has timed out, or you have disabled cookies.
As you don't have a session started, with this request a new session is created. Next time you try to login, as the session was created, you can login.
You had to set the option require_previous_session: false in your app/config/security.yml file to avoid looking for a previous session:
security:
firewalls:
main:
form_login:
require_previous_session: false

Symfony2: Unable to find the controller for path "/en/login_check"

I am working on creating a login form in Symfony, following the example provided in the Security chapter of the Symfony book.
I have created the necessary configurations in security.yml, routing.yml and also implemented my ControllerAction and Twig template.
Here is what the security and routing files look like:-
security.yml
Firewalls:
# defaut login area for standard users
main:
switch_user: true
context: user
pattern: .*
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: /login_check
failure_path: null
logout: true
anonymous: true
routing.yml
login:
pattern: /{_locale}/login
defaults: { _controller: XYZSiteBundle:SiteUser:login }
login_check:
pattern: /{_locale}/login_check
As you can see, the login_path and check_path are both under the same firewall.
I am still getting the following error:-
Unable to find the controller for path "/en/login_check". Maybe you forgot to add the matching route in your routing configuration?
What am I doing incorrectly?
Your configuration setting is almost OK.Your problem is related to routing. You can solve this issue by just change your routing.yaml to
In routing.yaml
login:
pattern: /login defaults: { _controller:XYZSiteBundle:SiteUser:login }
login_check:
pattern: /login_check
because you \login and \logincheck pattern must match with security.yaml pattern. You need to remove /{_locale}/login and /{_locale}/login_check.
Hope this helps you.
The check_path value of your form_login section will not match /en/login_check.
You have to modify it to match /.*/login_check.
Your login_check route is missing controller default, should be:
login_check:
pattern: /{_locale}/login_check
defaults: { _controller: XYZSiteBundle:SiteUser:loginCheck }