Symfony: Wrong firewall used when session expires - php

I have a Symfony app which used FOSUserBundle (not sure that matters as it's an issue with the Firewall). It has 2 firewalls, both for different sections of the site. One is the front end and the other an admin area.
The issue I'm having is that when the user logs in to the front end and after their session expires (if they didn't choose to remember login), they are redirected to the admin firewall logout target.
Here's the firewall configuration in my security file:
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_CLIENT: ROLE_USER
ROLE_ACCOUNT_MANAGER: ROLE_CLIENT
ROLE_DESIGNER: ROLE_USER
ROLE_PUBLISHER: ROLE_DESIGNER
ROLE_ADMIN: [ROLE_PUBLISHER, ROLE_ACCOUNT_MANAGER]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
site:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
always_use_default_target_path: true
default_target_path: site_survey_launch
login_path: site_login
check_path: site_login_check
use_referer: true
success_handler: xd_authentication.event.listener
logout:
path: site_logout
target: site_login
success_handler: xd_authentication.event.listener
anonymous: true
portal:
pattern: ^/portal
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
always_use_default_target_path: true
default_target_path: portal_user_surveys_live
login_path: portal_login
check_path: portal_login_check
logout:
path: portal_logout
target: portal_login
anonymous: true
context: shared
acl:
connection: default
The success_handler handler for the site logout configuration returns a redirect response for site_login. Even more reason to be fairly confused about this issue. Unless the success_handler is only used for a manual logout process.
Any help with this would be greatly appreciated. I've been trying to figure out what's going on for a few months now.

I think that order of firewall definitions is important, because site has pattern ^/ and I think that it processing request from ^/portal url. You should define portal firewall before site firewall.

Related

How to connect from SonataAdmin authenticator to other authenticator?

I have a symfony application which has inside the Sonata Admin Bundle for the admin part, with it's own firewall (admin) and the firewall for the user part of the application (main).
At the moment, the admin which is connected with sonata can't access the API that is designed for the user because it is authenticated for the Sonata Admin Bundle authenticator and for the API it sees him as a null user or not authenticated one.
I want to allow the admin to access an API that is made for the part of the application that is behind the firewall for the user part.
Config for the firewalls in the security.yaml file:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin:
pattern: ^/admin(.*)
form_login:
provider: app_user_admin
login_path: admin_login
use_forward: false
check_path: admin_login
failure_path: null
logout:
path: admin_logout
target: admin_login
anonymous: true
guard:
authenticators:
- App\Security\AdminLoginAuthenticator
main:
anonymous: true
logout:
path: security_logout
guard:
authenticators:
- App\Security\UserLoginAuthenticator
Is there a way to can connect the two authenticators for the admin? Like, on a success login for the admin to call the authenticator for the main firewall?
After some digging and some help, I found out that symfony security has something like this built in.
It's called Symfony context and does the exact same thing.
For future reference, this is what you really need to add to the config file:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin:
context: just_a_random_name
pattern: ^/admin(.*)
form_login:
provider: app_user_admin
login_path: admin_login
use_forward: false
check_path: admin_login
failure_path: null
logout:
path: admin_logout
target: admin_login
anonymous: true
guard:
authenticators:
- App\Security\AdminLoginAuthenticator
main:
context: just_a_random_name
anonymous: true
logout:
path: security_logout
guard:
authenticators:
- App\Security\UserLoginAuthenticator

Symfony redirect loop to /login only on production server

Note: Obviously there are a lot of duplicate/similar questions on here, but the solutions on those questions didn't help me.
I am moving a Symfony3 app to a new server, and it's causing me a lot of problems. At the moment, when I go to the home page (or any other), I get stuck in a redirect loop to the /login path.
It has worked for a long time on MAMP and on a previous CentOS server, but now on Ubuntu it's not working. I also had some file permission issues (var/cache, var/logs), which may or may not be related.
This is my security.yml
security:
role_hierarchy:
ROLE_ADMIN: [ROLE_MOD, ROLE_ALLOWED_TO_SWITCH]
ROLE_MOD: ROLE_USER
encoders:
AppBundle\Entity\User:
algorithm: bcrypt
providers:
our_db_provider:
entity:
class: AppBundle:User
property: username
firewalls:
main:
pattern: ^/
http_basic: ~
provider: our_db_provider
anonymous: ~
switch_user: true
form_login:
login_path: login
check_path: login
csrf_token_generator: security.csrf.token_manager
logout:
path: /logout
target: /
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }

symfony2 configuring the firewall - weird behaviour at login

I am using symfony2 with FOSUserBundle and i am trying to set up correctly my firewall.
I want the major part of my website to not be available to anonymous users. Home page (the $ in the public pattern) and some others should be available according to a pattern.
With my current configuration, after login I am redirected to the home page but still as anonymous. If i directly type a url of a page not allowed to anonymous directly afterwards, I can access it and I am logged (in the profiler).
My configuration:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
public:
pattern: /(login$|register|resetting|public|$)
anonymous: true
main:
pattern: ^/
anonymous: false
provider: main
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
logout:
path: fos_user_security_logout
target: /
What can I do to make it work properly (logged correctly after login).
EDIT:
I understand better what is happening: after login, I am being redirected to the home page=root address. This falls first into the public firewall and that's whay I'm not seen as connected.
Well you always can hardcode the path that you're redirected after login (in your security.yml file). You can read more here
security:
firewalls:
main:
form_login:
default_target_path: default_security_target
Done! Solution involves the context property of the firewall which is better described here :
Authenticate multiple symfony2 firewalls with one login form
My configuration now becomes:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
guest:
pattern: /(user/login$|user/register|user/resetting|$)
anonymous: true
context: main_auth
main:
pattern: ^/(?!user/login$)
anonymous: false
provider: main
context: main_auth
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
logout:
path: fos_user_security_logout
target: /
remember_me:
key: "%secret%"
lifetime: 86400 # 365 jours en secondes
path: /
domain: ~ # Prend la valeur par défaut du domaine courant depuis $_SERVER
oauth:
remember_me: true
resource_owners:
facebook: "/loginhwi/check-facebook"
github: "/loginhwi/check-github"
google: "/loginhwi/check-google"
twitter: "/loginhwi/check-twitter"
linkedin: "/loginhwi/check-linkedin"
flickr: "/loginhwi/check-flickr"
login_path: fos_user_security_login
check_path: fos_user_security_check
failure_path: fos_user_security_login
success_handler: foodmeup_user.handler_auth
oauth_user_provider:
service: fosubuser.provider

Symfony session, different route, different session

So, i have two differents route on my project :
/memberarea
/mobile
The first is for the web version on my application, and the second is for the mobile version.
Here you can see a part of my security.yml :
firewalls:
main:
pattern: ^/
form_login:
login_path: /
provider: fos_userbundle
csrf_provider: form.csrf_provider
default_target_path: /memberarea
logout: true
anonymous: true
mobile:
pattern: /mobile/.*
logout: true
anonymous: true
access_control:
- { path: ^/memberarea, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/mobile, roles: IS_AUTHENTICATED_FULLY }
My problem, when a user login on mobile, i create a session on symfony with the firewall mobile like : $token = new UsernamePasswordToken($user, $request->get('password'), "mobile", $user->getRoles());.....
this user can use all route in /mobile, it's ok. But he can use /memberarea too.
How can i do for login a user just for /mobile, just for /memberarea or for both ?
If I have correctly understood, you want to log into your mobile application with a different session than on your web application.
What I am doing in order to obtain this result is setting up in my security.yml file a different context for each firewall I have.
(If you want to have one session for both you must have the context with the same value for the given firewalls.)
File: app/config/security.yml
firewalls:
main:
pattern: ^/
**context: user**
form_login:
login_path: /
provider: fos_userbundle
csrf_provider: form.csrf_provider
default_target_path: /memberarea
logout: true
anonymous: true
mobile:
pattern: /mobile/.*
*context: mobile_user*
logout: true
anonymous: true
Hope this helped.

Symfony 2 User security from one bundle to other bundle

I am new to Symfony 2 and never used any framework before.
I created 2 bundles, one for core site which url is as root / it is DefaultBundle then I created a new UserBundle and set all the routing to /user/ the login page is /user/login and it is working fine.
So far I am able to login the user and every thing seems working.
Question really is, how can I check in DefaultBundle that a user is logged in, so I show them Welcome User instead of login/register links on top right side of the front end website.
p.s. I dont need FOSuserBundle as answer,
below is from my security.yml file
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
Aala\Vital\UserBundle\Entity\User:
algorithm: plaintext
# encode_as_base64: false
# iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_MOD: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_MOD, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
user_area:
entity: {class: AalaVitalUserBundle:User, property: email}
firewalls:
login:
pattern: ^/user/login$
security: false
anonymous: true
user_area:
pattern: ^/user
form_login:
login_path: /user/login
check_path: /user/login_check
post_only: true
default_target_path: /user/
logout:
path: /user/logout
target: /user/
main:
pattern: ^/
security: true
anonymous: ~
access_control:
- { path: /.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user, roles: ROLE_USER }
My Folder Structure is as follows
-src
-Aala
-Vital
-FronendBundle
-UserBundle
Edit:
Is this can be done with dependency injection? if yes how to do that...
Solved
To share the authentication between two firewalls use context. Below is the updated firewalls section from my security.yml file
firewalls:
login:
pattern: ^/user/login$
security: false
anonymous: true
user_area:
pattern: ^/user
context: primary_auth
form_login:
login_path: /user/login
check_path: /user/login_check
post_only: true
default_target_path: /user/
logout:
path: /user/logout
target: /user/
main:
pattern: ^/
context: primary_auth
security: true
anonymous: ~
According to the docs in a controller:
http://symfony.com/doc/current/book/security.html#retrieving-the-user-object
public function indexAction()
{
$user = $this->getUser();
if($user->isAuthenticated()) {
// Stuff
}
}
You can find it in the dosc here.
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
{{ 'Welcome ' ~ app.user.username }}
Logout
{% else %}
Login
{% endif %}
Change login_route and logout_route to meet routes of your application.
Why don't you want to use FOSUserBundle? It's a very good bundle, written by core members and e.g. you can find this code right here.
You will need the routes for both bundles to be behind the same firewall for $user = $this->getUser(); to work. Then you can allow anonymous access using ACL if you'd like a certain part of the site to be unauthenticated.
firewalls:
site:
pattern: ^/
anonymous: ~
form_login:
login_path: /user/login
check_path: /user/login_check
post_only: true
default_target_path: /
logout:
path: /user/logout
target: /user/
access_control:
- { path: ^/user/, roles: ROLE_USER}

Categories