How can you exit a switch_user by Symfony 3.4? - impersonation

I have a project with the possability to switch from user. The impersonator works, but I can't leave the impersonator. So I stay login with the user where I to switch.
For example: User A is login and switch to user B. When They click on /?_switch_user=_exit, then you expect that user is go back to user A. But the user stay by user B.
What can be the problem?
This information have I included in the security.yml:
firewalls:
main:
pattern: ^/
two_factor:
auth_form_path: 2fa_login
check_path: 2fa_login_check
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
check_path: fos_user_security_check
default_target_path: homepage
always_use_default_target_path: false #true
#csrf_token_generator: security.csrf.token_manager
logout:
path: fos_user_security_logout
target: /
anonymous: true
logout_on_user_change: false
switch_user: { role: ROLE_ADMIN }
Update: The user A is a ROLE_ADMIN and B is ROLE_CONSUMER
Routing:
home_redirect:
path: /{_locale}
defaults: { _controller: AppBundle:Default:index, _locale: 'nl' }
requirements:
_locale: nl|en|fr
app:
resource: '#AppBundle/Controller/'
prefix: /{_locale}
defaults: {_locale: 'nl'}
type: annotation
requirements:
_locale: nl|en|fr
Update 2:
The error what is comming by redirect to exit:
error of wrong user
Thanks for the help!

Since you're linking to root using /?_switch_user=_exit, ensure that your firewall definition covers that path:
main:
pattern: ^/

Related

Symfony 2 anon access with security context

I am working on a project where a url under the path /video/ should be available both anonymously and logged in. If the user is logged in they should see some additional elements, a form for example. However, if i allow anonymous access i get no security context and cannot check if user is authenticated to show the extra elements.
This are the two configuration variants i have tried:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/user/login$
security: false
secured_area:
pattern: ^/
form_login:
check_path: _security_check
login_path: /user/login
logout:
path: _user_logout
target: _user_login
#anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
access_control:
- { path: ^/video/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
However in that case you need to log in, in the other case i cannot get security context to check if user is logged in:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/user/login$
security: false
video:
pattern: ^/video/
anonymous: ~
secured_area:
pattern: ^/
form_login:
check_path: _security_check
login_path: /user/login
logout:
path: _user_logout
target: _user_login
#anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
access_control:
- { path: ^/video/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
How do i go about to achieve this simple thing?
The second solution is almost correct.just share the context of 'video' and 'secured_area' firewall.that is give them the same context value i.e:
video:
path: ^/video/
anonymous: ~
context: foobar #this is the line in question
secured_area:
....#same as what you wrote
context: foobar
this way if you're logged in, in secured_area the session will be accessible in video firewall.also there is need to login if the user is trying to access ^/video/ anonymously

Symfony2 - 2 firewalls, 1 login

Question: I want to create an admin part in my Symfony2 website that would be available only to users with a ROLE_ADMIN
I don't know if I should create a new firewall or use acces controls. I tried to do both together but the admin part is still accessible to all users.
Currently all the website is under secured area firewall and pages i want available to anonymous are freed with access control.
Here is my security.yml
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
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_email
my_facebook_provider:
id: my_user.facebook_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
context: login
admin:
pattern: /admin/
form_login:
provider: fos_userbundle
check_path: /login_check
login_path: /login
anonymous: ~
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: /login
check_path: /login_check
default_target_path: tk_group_homepage
provider: fos_userbundle
remember_me: true
csrf_provider: form.csrf_provider
remember_me:
key: %secret%
lifetime: 31536000 # 365 days in seconds
fos_facebook:
app_url: "%api_facebook_name%"
server_url: "%api_facebook_server%"
check_path: /login_facebook_check
default_target_path: tk_user_homepage
provider: my_facebook_provider
logout:
path: fos_user_security_logout
target: fos_user_security_login
invalidate_session: false
context: login
access_control:
- { path: ^/$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/new, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/invitation, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(subscribe|about|blog|press|contact), role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/admin/, role: ROLE_ADMIN }
I am also thinking about checking in the controller is the user has an admin role and throwing an exception if not, as my admin part is only one page currently. But I do not know if it is best practice and it could be a problem if i want to extend my admin part.
And I do not want to create a new user provider as we would be only 2 admins.
Thank you very much,
Jules
You should remove the admin firewall and rely on access_control; If you have admin login form under the /admin/ URL, you of course will not be able to see it before logging in, so you should either use the /login form to sign in as admin, or modify your access_control:
- { path: ^/admin/login/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
here is what official doc says about your situation:
Multiple firewalls don't share security context If you're using multiple firewalls and you authenticate against one firewall, you will
not be authenticated against any other firewalls automatically.
Different firewalls are like different security systems. To do this
you have to explicitly specify the same Firewall Context for different
firewalls. But usually for most applications, having one main firewall
is enough.
http://symfony.com/doc/current/book/security.html#book-security-common-pitfalls
You should read the whole Common pitfalls section
If you would really really like to use different firewalls, just do as the documentation states, and share the same firewall context beetween them. This is also described in the documentation:
http://symfony.com/doc/current/reference/configuration/security.html#reference-security-firewall-context
and here is a simple example:
admin:
(... other options ...)
context: my_security_context
secured_area:
context: my_security_context
(... other options ...)
The Access Control looks for the first match.
Because of that you need to put this line:
- { path: ^/admin/, role: ROLE_ADMIN }
Before this line:
- { path: ^/$, role: IS_AUTHENTICATED_ANONYMOUSLY }
If you do not, /admin/whatever matches the path ^/$ and needs no ROLE_ADMIN.

app.user is not accessible from unsecured area

How is it possible to get app.user from unsecure area?
So I have secured area which starts from ^/user.
But I need to display logout form on area which is accessible for everyone and not secured. How is this possible? My security.yml:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
###:
algorithm: sha512
encode-as-base64: true
iterations: 10
###:
algorithm: sha512
encode-as-base64: true
iterations: 10
role_hierarchy:
providers:
admin:
name: admin
entity: { class: ###, property: login }
user:
name: user
entity: { class: ###, property: login }
firewalls:
admin:
pattern: ^/admin
form_login:
login_path: ###_login
check_path: ###_login_process
default_target_path: /admin/dashboard
anonymous: ~
logout:
path: /admin/logout
target: /admin/login
provider: admin
remember_me:
key: "###"
lifetime: 604800
path: /
domain: ~
user:
pattern: ^/user
form_login:
login_path: ###_login
check_path: ###_login_process
default_target_path: ###
anonymous: ~
logout:
path: /user/logout
target: /user/login
provider: user
remember_me:
key: "###"
lifetime: 604800
path: /
domain: ~
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, roles: ROLE_ADMIN }
- { path: ^/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/, roles: ROLE_USER }
Well I changed a little bit my security.yml. So currently everything works ok.
user:
pattern: ^/
access_control:
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
...
UPDATE 1
It seems that line in access_controll is not required. Moreover by some reason(might be cache) anonymoous users were accessing /user areas
You can get app.user in some unsecured area because Symfony security relies on 2 different mechanisms: authentication and authorization.
Authentication is defined by firewalls. As soon as you get under a firewall, you get a token and eventually a app.user, even if it is anonymous.
Authorization is related to access_control rules. It is a second step, you can't put access control rules outside of a firewall. There you will deal with the ROLE requirement, in example if ROLE_ANONYMOUS is enoug, if you want ROLE_USER...
One more thing: to complexify a little further, a firewall can allow or disallow anonymous users. By default it is true, as it is required to have you login and login_check paths under yoru firewall though you cant' require there users to have a role other than ROLE_ANONYMOUS (if you do so, you will have an infinite loop).

Symfony-2 > login & logout routes with placeholders

I am using Symfony-2 to implement my application.
I need my login and logout routes to have some placeholders, but I don't manage to define it well in routing.yml and security.yml files.
I want to have something like:
www.mysite.com/{client_slug}/panel
and under it other secured pages:
www.mysite.com/{client_slug}/panel/.*
When someone tries to navigate to one of these pages, he/she should be redirected to:
www.mysite.com/{client_slug}/login
and after clicking logout, user should be redirected to something like:
www.mysite.com/{client_slug}/goodbye
I tried several things (http://forum.symfony-project.org/viewtopic.php?f=23&t=37809) but at the moment the only thing I achieved was that in my login url the text {client_slug} appears:
www.mysite.com/my-cliend-slug/panel
redirects to
www.mysite.com/{client_slug}/login
security.yml
firewalls:
main:
pattern: /.*
form_login:
check_path: /login_check
login_path: _security_login
logout:
path: /logout
target: /goodbye
security: true
anonymous: true
routing.yml
_security_login:
pattern: /{_client_slug}/login
defaults: { _controller: MyAppBackendBundle:Security:login }
_security_check:
pattern: /login_check
_security_logout:
pattern: /logout
_admin_panel:
pattern: /{_client_slug}/panel
defaults: { _controller: MyAppBackendBundle:AdminPanel:index }
Any ideas?
I had the exact same problem. I've read everything from here (http://forum.symfony-project.org/viewtopic.php?f=23&t=37809) and for me it works with a few extra lines.
Here is my security.yml
login_area:
pattern: ^/[A-Za-z0-9\-\_]+/login$
anonymous: ~
secured_area:
pattern: ^/[A-Za-z0-9\-\_]+/.*
form_login:
login_path: login
check_path: login_check
logout:
path: logout
target: /
remember_me:
key: "%secret%"
lifetime: 31536000
path: /
domain: ~
The login and login_path definitions:
login:
pattern: /{_client}/login
defaults: { _controller: GNCApplicationBaseBundle:Security:login }
login_check:
pattern: /{_client}/login_check
And I made an EventListener, which will be called at the kernel.request event:
acme.system.client.listener:
class: Acme\System\ClientBundle\EventListener\ClientListener
arguments: [#router, #doctrine.orm.entity_manager]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 10 }
The important attribute is the priority. In the Symfony Documentation (http://symfony.com/doc/current/reference/dic_tags.html#kernel-event-listener) it shows that the RouterListener starts with a priority 32 and the Firewall at 8. So I choose to call my custom EventListener right before the Firewall and set the _client-attribute manually in the router-context:
public function onKernelRequest(GetResponseEvent $event) {
$clientIdentifier = $event->getRequest()->attributes->get('_client');
$this->router->getContext()->setParameter('_client', $clientIdentifier);
}
And it works well for me.
I'm currently using Symfony 2.2.0-RC3.

Symfony2 Security problem

i'm going to adapt my web project (based on symfony2 PR5) to symfony2 PR7. Everything is pretty clear with this migration except the Security bundle. Here is my security configuration:
security:
encoders:
Application\PermissionsBundle\Entity\Stuff: sha1
providers:
main:
entity: { class: PermissionsBundle:Stuff, property: username}
firewalls:
main:
pattern: .*
form_login:
check_path: /login-check-admin
login_path: /login-admin
failure_path: /login-admin
logout: true
anonymous: true
backend:
pattern: /admin.*
form_login:
check_path: /login-check-admin
login_path: /login-admin
logout: true
security: true
anonymous: false
access_control:
- { path: /admin.*, role: ROLE_ADMIN }
Routing configuration:
_security_login:
pattern: /login-admin
defaults: { _controller: PermissionsBundle:Security:login }
_security_check:
pattern: /login-check-admin
_security_logout:
pattern: /logout-admin
_security_status:
pattern: /sec_status
defaults: { _controller: PermissionsBundle:Security:status }
_security_get_username:
pattern: /security/get/username
defaults: { _controller: PermissionsBundle:Security:getUserName }
When I try to authenticate, I get a 404 fpr login checking:
Firebug output: http://impic.ru/uploads/2011/2303/53849205_61601933.jpeg
Can anybody please help me with this problem? This code works fine in PR5, but not in PR7. Official symfony documentation hasn't changed yet. Maybe I'm missing something?
The solution is simple. You cannot customize logout and login_check routing patterns. It means that your security.yml file should looks like this:
form_login:
check_path: /login_check
login_path: /login
and your routing.yml file should looks like this:
_security_check:
pattern: /login_check
_security_logout:
pattern: /logout
These work perfect for me.

Resources