Symfony2, переключитесь на HTTPS после аутентификации
Я хочу заставить пользователя использовать HTTPS вместо HTTP, но только после аутентификации. Единственный вариант, который я нашел, - это принудительное использование HTTPS для каждого контроллера/метода. Анонимные пользователи должны использовать только HTTP.
Как установить принудительный HTTPS только для пользователей, прошедших проверку подлинности, и заставить НЕ использовать HTTPS для пользователей, не прошедших проверку подлинности, во всех контроллерах в моем пакете?
Опять же - речь не идет об отключении HTTPS для страницы авторизации.
Я хочу использовать все те же контроллеры для аутентифицированные и не прошедшие проверку подлинности пользователи, но заставляют тех, кто вошел в систему, использовать HTTPS, а тех, кто не должен использовать HTTP. В основном добавьте требование к HTTPS для ВСЕХ контроллеров, когда пользователь аутентифицируется.
Этот вопрос специфичен для Symfony 2. Я хочу сделать это с помощью механизмов Symfony. Я знаю, как обнаружить эту штуку, но она разорвет связи между ветками. Symfony может автоматически переключаться на HTTPS, я просто хочу знать, как это сделать для каждой роли пользователя, а не для каждого контроллера.
2 answers
Можно было бы подумать, что контроллер доступа сделает это за нас:
access_control:
- { role: ROLE_USER, requires_channel: https }
- { role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: http }
Но, нет... Я думаю, что это было бы очень хорошей функцией, хотя.
В этом случае мы можем взломать что-то вместе с прослушивателем запросов, используя события ядра:
namespace YourBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
class RequestListener
{
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
// force ssl based on authentication
if ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) {
if (!$request->isSecure()) {
$request->server->set('HTTPS', true);
$request->server->set('SERVER_PORT', 443);
$event->setResponse(new RedirectResponse($request->getUri()));
}
} else {
if ($request->isSecure()) {
$request->server->set('HTTPS', false);
$request->server->set('SERVER_PORT', 80);
$event->setResponse(new RedirectResponse($request->getUri()));
}
}
}
}
Определите своего слушателя в файле config.yml в разделе службы:
myapp.request.listener:
class: MyApp\MyBundle\EventListener\RequestListener
tags:
- { name: kernel.event_listener, event: kernel.request }
Смотрите Внутренние компоненты Symfony для получения подробной информации о событиях и тому подобном.
В Symfony 2.0.11 я получаю ошибку перенаправления. Чтобы решить эту проблему, я прокомментировал следующие строки в прослушивателе.
class RequestListener {
public function onKernelRequest(GetResponseEvent $event) {
$request = $event->getRequest();
// force ssl based on authentication
if ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) {
if (!$request->isSecure()) {
$request->server->set('HTTPS', true);
$request->server->set('SERVER_PORT', 443);
// $event->setResponse(new RedirectResponse($request->getUri()));
}
} else {
if ($request->isSecure()) {
$request->server->set('HTTPS', false);
$request->server->set('SERVER_PORT', 80);
// $event->setResponse(new RedirectResponse($request->getUri()));
}
}
}
}