我希望删除在某处抛出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());
}
}
新问题是 - 它是否会导致任何安全问题? 我认为这是好方法。