首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Symfony 3.4 :如何强制解除身份验证

Symfony 3.4 :如何强制解除身份验证
EN

Stack Overflow用户
提问于 2019-11-08 11:30:44
回答 2查看 289关注 0票数 0

我的安全用户完全通过从某个系统获得的一些角色进行身份验证。我想检查其中一个角色是否存在,如果不存在,我想强制取消用户身份验证。

在登录时的事件侦听器中,我执行以下操作:

代码语言:javascript
代码运行次数:0
运行
复制
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应该要求取消用户身份验证吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-08 17:24:25

与检查控制器中的用户权限不同,您可以创建一个可根据自定义逻辑拒绝身份验证的自定义用户检查器。

示例用户检查器

代码语言:javascript
代码运行次数:0
运行
复制
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文件中的使用。

代码语言:javascript
代码运行次数:0
运行
复制
security:
    firewalls:
        main:
            pattern: ^/
            user_checker: AppBundle\Security\UserChecker

更多信息这里

票数 1
EN

Stack Overflow用户

发布于 2019-11-08 12:48:33

最简单的方法是将用户重定向到注销路由。

遗憾的是,似乎没有一个专门的方法可以简单地为您处理整个注销过程。除非您设法在有效的这种方法实例中调用Symfony\Component\Security\Http\Firewall\LogoutListener

Symfony注销的工作方式如下:

  • 它由此侦听器处理。
  • 每个请求都会调用侦听器。
  • 侦听器检查是否请求路由===注销路由
  • 如果请求路由===注销路由,侦听器将用户注销。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58765729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档