Symfony2 - 抛出AccessDeniedHttpException不起作用编辑:安全

时间:2016-06-09 02:14:24

标签: php symfony security authentication symfony-components

我希望删除在某处抛出AccesDeniedException时重定向的不良影响。我的意思是,如果用户未经过身份验证,则重定向到“登录”页面。

我创建了kernel.exception侦听器

class ApiAccessDeniedListener implements EventSubscriberInterface
{
    private $format;

    public function __construct($format = 'json')
    {
        $this->format = $format;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $exception = $event->getException();
        // here some conditions
        if($exception instanceof AccessDeniedException){
            $exception = new AccessDeniedHttpException('You do not have the necessary permissions', $exception);
        }
    }

    public static function getSubscribedEvents()
    {
        return array(
            KernelEvents::EXCEPTION => array('onKernelException', 5),
        );
    }
}

此侦听器以正确的顺序正常工作,但所有时间防火墙都会将我重定向到登录页面。 Symfony docs say那个:

  

异常侦听器

     

如果任何侦听器抛出AuthenticationException,则   在向安全区添加安全区域时提供的异常监听器   防火墙地图将跳入。

     

异常监听器根据具体情况确定接下来会发生什么   它在创建时收到的参数。它可能会开始   验证程序,也许要求用户提供他们的   凭证再次(当它们仅基于a进行身份验证时)   “记住我”cookie,或将异常转换为    AccessDeniedHttpException ,最终会导致   “HTTP / 1.1 403:拒绝访问”响应。

我理解 - 如果我抛出AccessDeniedHttpException我应该立即获得403而不是重定向, 我是对的吗?

第二 - 我挖了symfony,ExceptionListener有同样的伎俩?我想......

private function handleAccessDeniedException(GetResponseForExceptionEvent $event, AccessDeniedException $exception)
{
    $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
    //...
}

此外,symfony调试器在auth之后显示2个异常。 (应该如此):

Unable to access this page!
403 Forbidden - AccessDeniedHttpException
1 linked Exception: ... (and here AccessDeniedException)

首先AccessDeniedException和第二AccessDeniedHttpException

我该如何解决我的问题?如何抛出403错误?

修改

我发现问题出在哪里。防火墙ExceptionListener使用循环检查所有先前的异常:

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $exception = $event->getException();
        do {
            if ($exception instanceof AuthenticationException) {
                return $this->handleAuthenticationException($event, $exception);
            } elseif ($exception instanceof AccessDeniedException) {
                return $this->handleAccessDeniedException($event, $exception);
            } elseif ($exception instanceof LogoutException) {
                return $this->handleLogoutException($exception);
            }
        } while (null !== $exception = $exception->getPrevious());
    }

我可以改变我的听众:

public function onKernelException(GetResponseForExceptionEvent $event)
{
    $exception = $event->getException();
    // here some conditions
    if($exception instanceof AccessDeniedException){
        //old version
        //$exception = new AccessDeniedHttpException('You do not have the necessary permissions', $exception);
        $exception = new AccessDeniedHttpException('You do not have the necessary permissions', $exception->getPrevious());
    }
}

新问题是 - 它是否会导致任何安全问题? 我认为这是好方法。

0 个答案:

没有答案