重写前日志中的 AccessDeniedException

AccessDeniedException in log before rewriting

在 4.1 中,当用户想要访问具有安全性的页面(例如@Security("has_role('ROLE_ADMIN')")时,用户将在登录页面中重定向。它正在运行。我没有错误 500。

但是在我的日志中 /var/log/prod.log 我有一些错误 :

[2018-06-06 09:30:47] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Security\Core\Exception\AccessDeniedException: "Access Denied." at /var/www/website/vendor/symfony/security/Http/Firewall/AccessListener.php line 68 {"exception":"[object] (Symfony\Component\Security\Core\Exception\AccessDeniedException(code: 403): Access Denied. at /var/www/website/vendor/symfony/security/Http/Firewall/AccessListener.php:68)"} []
[2018-06-06 09:30:47] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\Component\Security\Core\Exception\AccessDeniedException(code: 403): Access Denied. at /var/www/website/vendor/symfony/security/Http/Firewall/AccessListener.php:68)"} []
[2018-06-06 09:30:47] security.DEBUG: Calling Authentication entry point. [] []

我不明白为什么会出现严重错误。

Symfony Framework 定义了一个 Symfony\Component\HttpKernel\EventListener\ExceptionListener 订阅 KernelEvents::EXCEPTION 并且方法 logKernelException 的优先级非常高 2048 (参见 https://github.com/symfony/http-kernel/blob/master/EventListener/ExceptionListener.php#L93) :

public static function getSubscribedEvents()
{
    return array(
        KernelEvents::EXCEPTION => array(
            array('logKernelException', 2048),
            array('onKernelException', -128),
        ),
    );
}

因此抛出的 AccessDeniedException 首先由此 logKernelException 方法处理,该方法将其记录为 CRITICAL 级别(参见 https://github.com/symfony/http-kernel/blob/master/EventListener/ExceptionListener.php#L109):

protected function logException(\Exception $exception, $message)
{
    if (null !== $this->logger) {
        if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
            $this->logger->critical($message, array('exception' => $exception));
        } else {
            $this->logger->error($message, array('exception' => $exception));
        }
    }
}

在这一步,AccessDeniedException 已经登录到 request 频道。它与请求范围完全相关:原始请求失败,因为未执行身份验证...

然后,Symfony\Component\Security\Http\Firewall\ExceptionListener,侦听KernelEvents::EXCEPTION但仅处理与身份验证相关的内容(参见https://github.com/symfony/security/blob/master/Http/Firewall/ExceptionListener.php#L87)继续履行职责以重定向到身份验证起点...