Bug Symfony2 isGranted('MY_ROLE') returns true 但防火墙 returns 403

Bug Symfony2 isGranted('MY_ROLE') returns true but firewall returns 403

我正在使用 AuthenticationSuccessHandlerInterface 侦听器为我的用户动态添加角色。

public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
    $user = $this->security->getToken()->getUser();
    $user->addRole('MY_ROLE');

    var_dump($this->security->isGranted('MY_ROLE'));
    var_dump($this->security->getToken()->getRoles()); die;

    return new RedirectResponse('...');
}

两个 var_dump() 都显示 $user 获得了新的权利。 我制作了 User class 实现 EquatableInterface class 并在其中制作了一个 isEqualTo 函数以在我更改它时重新加载我的用户数据而无需任何注销。

public function isEqualTo(UserInterface $user)
{
    return false;
}

但是当达到我的侦听器重定向时,我在没有分析器的白页中得到一个 Access Denied

access_control:
    - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/login/check$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: MY_ROLE }

我已经尝试在 class 中设置角色(在代码中不是动态的),它工作正常,所以我的防火墙似乎工作正常,除了动态设置数据,即使我重新加载用户也是如此。

知道那里出了什么问题吗?

您可以尝试将此添加到您的 app/security.yml 中:

security:
    always_authenticate_before_granting: true

我终于解决了这个问题,使用带有 security.interactive_loginkernel.request 事件的事件侦听器。

我在会话中(在我为 security.interactive_login 事件注册的操作中)设置了一个键,并在 kernel.request 事件中签入(捕获对网站的每次调用)如果该键设置为做一件事或其他。

希望这可以帮助某人...