我有一个User
实体,它有一个布尔列isActivated
。根据每个用户的列值,他可能无法登录(即他没有激活他的帐户,所以没有登录(。我通过在防火墙中分配一个simple_form.authenticator
来实现这一点,该在每次登录时进行检查。
我试图弄清楚如何在用户仍在登录时强制注销用户。
请考虑以下方案:
- 用户在其帐户仍处于活动状态时登录。
- 管理员停用用户的帐户。
- 用户由于不再处于活动状态而注销。
不幸的是,步骤#3没有发生。原因可能在于用户已经收到了令牌,并且被Symfony 2.5
的防火墙视为"扰动"(令牌可能缓存在安全上下文中?
我想知道克服这个问题的最佳方法是什么?我应该编写内核事件侦听器还是自定义用户提供程序?
您可以使用
以下两行终止用户的会话(如果您有权访问容器,否则必须注入security.context
和session
(:
$container->get('security.context')->setToken(null);
$container->get('session')->invalidate();
之后,用户应注销。
如果之前已加载用户实体,则可能还需要取消设置该实体。
虽然@lxg回答了我的问题,但我决定扩展他的回答,以便其他有相同问题的人更好地了解如何解决这个问题。
创建事件侦听器
namespace Acme'MyBundle'Events;
use Acme'MyBundle'Entity'User;
use Symfony'Component'HttpKernel'Event'GetResponseEvent;
use Symfony'Component'Security'Core'Exception'AuthenticationCredentialsNotFoundException;
use Symfony'Component'Security'Core'SecurityContext;
class RequestEvent {
/**
* @var 'Symfony'Component'Security'Core'SecurityContext
*/
private $securityContext;
public function __construct(SecurityContext $context){
$this->securityContext = $context;
}
public function onKernelRequest(GetResponseEvent $event)
{
// not sure if this is actually needed?
if (!$event->isMasterRequest()) {
// don't do anything if it's not the master request
return;
}
// try to get security context and catch the exception in case no firewall was configured (i.e. for the dev tool bar)
try{
// trigger only for logged in users
if($this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')){
$token = $this->securityContext->getToken();
/**
* @var User $user
*/
$user = $token->getUser();
if($user != null && !$user->isActive()){
$this->securityContext->setToken(null);
}
}
} catch(AuthenticationCredentialsNotFoundException $e){
// don't do anything here... or do whatever you want.
}
}
}
?>
现在在您的service.yml
中添加以下内容:
services:
kernel.listener.request_listener:
class: Acme'MyBundle'Events'RequestEvent
arguments: [ @security.context ]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
一旦用户被停用,他将被强制重定向到防火墙的登录页面。希望这对某人有所帮助。