я бы хотел Удалить нежелательный эффект перенаправления, когда куда-то выбрасывается 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 документы говорят тот:
Слушатель исключений
Если какой-либо из слушателей выдает исключение AuthenticationException,
прослушиватель исключений, который был предоставлен при добавлении защищенных областей в
карта брандмауэра будет прыгать.Слушатель исключений определяет, что будет дальше, на основе
аргументы он получил, когда он был создан. Это может начать
Процедура аутентификации, возможно, попросите пользователя предоставить свои
учетные данные снова (когда они были аутентифицированы только на основе
«Помни меня» или превратить исключение в
AccessDeniedHttpException, что в конечном итоге приведет к
«HTTP / 1.1 403: доступ запрещен».
Я понимаю — если я брошу AccessDeniedHttpException
я должен получить мгновенный 403 вместо перенаправления,
Я прав?
Второе — я выкопал Symfony и ExceptionListener есть такой же трюк? Я думаю…
private function handleAccessDeniedException(GetResponseForExceptionEvent $event, AccessDeniedException $exception)
{
$event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
//...
}
Кроме того, отладчик Symfony показывает 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());
}
}
Новый вопрос — это может вызвать проблемы с безопасностью?
Я думаю, что это хороший способ.
Задача ещё не решена.
Других решений пока нет …