Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 2.6.6 security - How to logout or reset TokenStorage with user provider using in_memory?

I have symfony 2.6.6 installed, and I followed this tutorial until step 1.) b.) http://symfony.com/doc/2.7/book/security.html

1.) How to clear tokenStorage (session, etc) after logging in via http_basic?

after logging in by http_basic I can't find any way to clear my tokenStorage

Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage Object
(
    [token:Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage:private] => Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken Object
        (
            [credentials:Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken:private] => 
            [providerKey:Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken:private] => default
            [user:Symfony\Component\Security\Core\Authentication\Token\AbstractToken:private] => Symfony\Component\Security\Core\User\User Object
                (
                    [username:Symfony\Component\Security\Core\User\User:private] => admin
                    [password:Symfony\Component\Security\Core\User\User:private] => kitten
                    [enabled:Symfony\Component\Security\Core\User\User:private] => 1
                    [accountNonExpired:Symfony\Component\Security\Core\User\User:private] => 1
                    [credentialsNonExpired:Symfony\Component\Security\Core\User\User:private] => 1
                    [accountNonLocked:Symfony\Component\Security\Core\User\User:private] => 1
                    [roles:Symfony\Component\Security\Core\User\User:private] => Array
                        (
                            [0] => ROLE_ADMIN
                        )

                )

            [roles:Symfony\Component\Security\Core\Authentication\Token\AbstractToken:private] => Array
                (
                    [0] => Symfony\Component\Security\Core\Role\Role Object
                        (
                            [role:Symfony\Component\Security\Core\Role\Role:private] => ROLE_ADMIN
                        )

                )

            [authenticated:Symfony\Component\Security\Core\Authentication\Token\AbstractToken:private] => 1
            [attributes:Symfony\Component\Security\Core\Authentication\Token\AbstractToken:private] => Array
                (
                )

        )

)

this is my security.yml

security:
    # http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

    # http://symfony.com/doc/current/book/security.html#hierarchical-roles
    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    # http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
    providers:
        in_memory:
            memory:
                users:
                    ryan:
                        password: ryanpass
                        roles: 'ROLE_USER'
                    admin:
                        password: kitten
                        roles: 'ROLE_ADMIN'

    # the main part of the security, where you can set up firewalls
    # for specific sections of your app
    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        default:
            anonymous: ~
            http_basic: ~
            logout:
                path:   /logout
                target: /
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/admin/logout, roles: ROLE_ADMIN }

p.s: At first access to /admin http basic form pops up as expected but after logging in and clearing cache, even the browser's still I cant cleanup tokenStorage

like image 720
Tyro Hunter Avatar asked Feb 03 '26 19:02

Tyro Hunter


2 Answers

I was struggling a bit with the recently myself. What I got to work was:

  1. Create a route for /logout & pass it to a the Default Controller logoutAction() function
  2. Add logoutAction() function to DefaultController.php that sets token to NULL and redirects you to root
#/app/config/routing.yml

#...
logout:
  path: /logout
    defaults: { _controller: AppBundle:Default:logout }
#/src/AppBundle/Controller/DefaultController.php

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\HttpFoundation\RedirectResponse;

class DefaultController extends Controller
{
    public function logoutAction() {
        $this->get('security.token_storage')->setToken(NULL);

        // Redirect User to Root/Hello/Wherever
        return new RedirectResponse($this->generateUrl('hello'));
    }
    //...
}

Note the additional "use" lines in DefaultController.php

like image 142
Durthar Avatar answered Feb 05 '26 08:02

Durthar


In Symfony, you can add your own success handler to logout route. So you can do something like below. This is a simple notation, using the logout path set in parameters.yml. In more elaborate example you can fetch the security component configuration and get the logout path from there, but this is much more complex.

This solution's advantage is that it plugs directly into security component flow - all other actions needed on log out are executed correctly.

parameters.yml

parameters:
    (...)
    %logout_target%: /
    (...)

security.yml

security:
    default:
            anonymous: ~
            http_basic: ~
            logout:
                path:   /logout
                target: /
                success_handler: your.success.handler.service

services.yml

parameters:
    logout_target: /
services:
    your.success.handler.service: 
        class: \Your\SuccessHandlerClass
        arguments:
            - @security.http_utils
            - @security.token_storage
            - %logout_target%

src/Your/SuccessHandlerClass.php

<?php

namespace Your;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;

class SuccessHandlerClass extends DefaultLogoutSuccessHandler
{
    /**
     *
     * @var TokenStorageInterface
     */
    private $tokenStorage;

    public function __construct(HttpUtils $httpUtils, TokenStorageInterface $tokenStorage, $targetUrl = '/')
    {
        parent::__construct($httpUtils, $targetUrl);
        $this->tokenStorage = $tokenStorage;
    }


    public function onLogoutSuccess(Request $request)
    {
        $this->tokenStorage->setToken(null);
        return parent::onLogoutSuccess($request);
    }
}
like image 25
Tomasz Struczyński Avatar answered Feb 05 '26 09:02

Tomasz Struczyński