Symfony 2.6.6安全性 - 如何使用in_memory注销或重置用户提供程序的TokenStorage?

时间:2015-04-16 08:55:23

标签: php symfony cookies session-cookies browser-cache

我安装了symfony 2.6.6,我按照本教程直到第1步。)b。) http://symfony.com/doc/2.7/book/security.html

1.。)如何通过http_basic登录后清除tokenStorage(会话等)?

在http_basic登录后 我找不到任何方法来清除我的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
                (
                )

        )

)
  
    

这是我的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:首先访问/ admin http基本表单按预期弹出,但登录并清除缓存后,即使浏览器仍然无法清理tokenStorage

  

2 个答案:

答案 0 :(得分:1)

我和最近的自己有点挣扎。我的工作是:

  1. 为/ logout&创建路由将它传递给默认控制器logoutAction()函数
  2. 将logoutAction()函数添加到DefaultController.php,将token设置为NULL并将您重定向到root
  3. #/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'));
        }
        //...
    }
    

    请注意DefaultController.php

    中的其他“使用”行

答案 1 :(得分:1)

在Symfony中,您可以添加自己的成功处理程序以注销路由。所以你可以做类似下面的事情。这是一个简单的表示法,使用在parameters.yml中设置的注销路径。在更详细的示例中,您可以获取安全组件配置并从那里获取注销路径,但这要复杂得多。

此解决方案的优势在于它可以直接插入安全组件流 - 注销时所需的所有其他操作都可以正确执行。

  

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 /你/ 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);
    }
}