Я думаю, что поступил неправильно. Я хотел знать, был ли URL-адрес за брандмауэром, но я думаю, что должен был попытаться выяснить, был ли текущий пользователь авторизован для запроса. По сути, знание того, что пользователю отказано в доступе к URL-адресу, означает, что URL-адрес должен находиться за брандмауэром, иначе доступ не мог бы быть запрещен.
Имея это в виду, я смог получить желаемый конечный результат. Это довольно просто, когда вы понимаете, как работает механизм безопасности ...
Symfony\Component\Security\Http\Firewall
слушает
kernel.request
событие
- Брандмауэр затем вызывает несколько прослушивателей событий, зарегистрированных в
security.yml
- Если обнаружено какое-либо нарушение безопасности (т. Е. Пользователь пытается получить доступ к чему-либо без входа в систему), выдается
AccessDeniedException
и отправляется событие kernel.exception
.
Symfony/Component/Security/Http/Firewall/ExceptionListener
прослушивает событие и запускает его метод onKernelException
, который решает, каким будет следующий шаг. В моем случае это запустит процесс аутентификации
Поскольку запуск процесса аутентификации - это то, чего я хотел избежать, я написал свой собственный прослушиватель событий, который перехватывает kernel.exception
до того, как ExceptionListener
Symfony делает. Я назначил слушателю события приоритет 1.
Это метод, который я написал:
public function handleException(GetResponseForExceptionEvent $event) {
$exception = $event->getException();
$request = $event->getRequest();
if ($request->getMethod() == 'POST') {
if ($exception instanceof AccessDeniedException) {
$response = new Response({err: 'not logged in'});
$event->setResponse($response);
}
}
}
Пока пользователь не авторизован и метод запроса POST, возвращается объект JSON (который также останавливает распространение события) вместо HTML для страницы входа. В противном случае, другие слушатели kernel.exception
отреагируют, и Symfony сможет заняться своими делами.
Итак, оригинальный вопрос остается без ответа, но я думаю, что это можно сделать, проверив, есть ли у пользователя доступ к действию. Symfony\Component\Security\Core\Authorization\AccessDecisionManager
похоже, это было бы полезно для этого.
Редактировать
Я не знаю, если этот метод только обрабатывает пользователей, которые не вошли в систему. Я еще не проверял его, но я думаю, что он также будет срабатывать, если (вошедший в систему) пользователь попытается получить доступ к действию это требует роли, которую они не получили. Если это вызывает проблемы, я бы попытался изменить его для использования метода Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver
isFullFledged($token)
, чтобы заботиться только о пользователях, которые не вошли в систему.