【问题标题】:Symfony 2.6.6 security - How to logout or reset TokenStorage with user provider using in_memory?Symfony 2.6.6 安全性 - 如何使用 in_memory 使用用户提供程序注销或重置 TokenStorage?
【发布时间】:2015-07-22 22:32:12
【问题描述】:

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

1.) http_basic登录后如何清除tokenStorage(session等)?

通过 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

【问题讨论】:

  • 你有没有试过去 url .../admin/logout注销?
  • @Med:这是我尝试解决问题的方法之一。我添加了一条路由`logout:path:/logout`然后访问了../logout 我也尝试了你的建议,但无论哪种方式都失败了

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


【解决方案1】:

最近我自己有点挣扎。我要做的是:

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

注意 DefaultController.php 中额外的“使用”行

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 像 Symfony 一样复杂,但似乎是正确的方法。谢谢!
    • 用 Symfony 4.3 试过,但它不起作用。没有错误,成功处理程序被调用,但用户仍然登录 Sa 到目前为止,我所能做的就是删除所有 Chrome 浏览器历史记录,以便用户最终注销。
    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 2018-12-05
    • 2012-05-27
    • 1970-01-01
    • 2018-06-18
    • 2021-10-21
    • 2019-09-20
    • 2011-08-09
    相关资源
    最近更新 更多