Symfony 3.4:如何强制取消身份验证
我的安全用户通过从某个系统获得的某些角色进行了完全身份验证。我想检查其中一个角色是否存在,如果不存在,我想强制用户取消身份验证 在登录时的事件侦听器中,我执行以下操作:Symfony 3.4:如何强制取消身份验证,symfony,security,Symfony,Security,我的安全用户通过从某个系统获得的某些角色进行了完全身份验证。我想检查其中一个角色是否存在,如果不存在,我想强制用户取消身份验证 在登录时的事件侦听器中,我执行以下操作: use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Co
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class SecurityEventSubscriber implements EventSubscriberInterface {
private $token;
private $checker;
private $container;
private $session;
public function __construct(TokenStorageInterface $token, AuthorizationCheckerInterface $checker, ContainerInterface $container, SessionInterface $session) {
$this->token = $token;
$this->checker = $checker;
$this->container = $container;
$this->session = $session;
}
public function login() {
if(!$this->checker->isGranted('IS_AUTHENTICATED_FULLY')) {
$this->session->invalidate();
$this->token->setToken(null);
throw new AccessDeniedException();
} else {
$user = $this->token->getToken()->getUser();
$roles = $user->getRoles();
$found = false;
foreach ($roles as $role) {
if($role->getRole() === $this->container->getParameter('role_expected')) {
$found = true;
break;
}
}
if(!$found) {
$this->session->invalidate();
$this->token->setToken(null);
throw new AccessDeniedException();
} else {
$user->removeAllRoles();
}
}
}
}
正如您所看到的,我试图使用setToken将其设置为null,但它不起作用(异常)
HGow我应该要求取消对用户的身份验证吗?最简单的方法是将用户重定向到注销路径 遗憾的是,似乎没有一个专门的方法可以简单地为您处理整个注销过程。 除非您设法调用了
Symfony\Component\Security\Http\Firewall\LogoutListener
的有效实例
Symfony注销的工作原理如下:
- 它由这个侦听器处理
- 每个请求都会调用侦听器
- 侦听器检查请求的路由是否===注销路由
- 如果请求的路由===注销路由,侦听器将注销用户
namespace AppBundle\Security;
use AppBundle\Security\User as AppUser;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class UserChecker implements UserCheckerInterface
{
public function checkPreAuth(UserInterface $user)
{
if (!$user instanceof AppUser) {
return;
}
if (!in_array('SOME_ROLE', $user->getRoles())) {
// throw an AccountStatusException exception here
}
}
}
如果您还希望在用户登录后对用户角色进行检查(如果他的角色在会话期间可能发生更改),则可以使用checkPostAuth()
方法
您还必须提到在
app/config/security.yml
文件中使用自定义用户检查器
security:
firewalls:
main:
pattern: ^/
user_checker: AppBundle\Security\UserChecker
更多信息当侦听器自身被实例化时,会话可能尚未创建。您可以尝试注入RequestStack,然后在登录方法中从主请求获取会话。不确定它是否真的有用。虽然不相关,但您也应该仅使用role_预期参数替换容器。您似乎需要检查正在验证的用户的角色。如果用户角色不包含您想要拒绝他的身份验证的角色,对吗?似乎使用注销路由只是从会话中删除用户,但是如果我查看开发工具栏,用户仍然是经过身份验证的。我想做的不是在工具栏中看到经过身份验证的,只是为了确定。用户仍然经过身份验证:有可能,用户是匿名身份验证的吗?