Как я могу принудить аутентифицированного пользователя к HTTPS в Symfony2 только после полной аутентификации?
Мне нужно использовать https в Symfony 2.2, но только если пользователь полностью аутентифицирован.
2 ответа
Решение
Только что получил решение с помощью прослушивателя событий onKernalRequest.
Мой сервис событий onKernelRequest:
<?php
namespace Acme\DemoBundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* force https for fully authenticated user
*/
class ForceHttpsListner
{
/**
* container
*
* @var type
*/
private $container;
/**
*
* @param type $container
*/
public function __construct($container)
{
$this->container = $container;
}
/**
* on kernel request
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
//all urls which always use https, specefied using requires_channel in security.yml
$httpsPaths= [
'/login',
'/resetting/request',
'/register/',
];
if ($event->getRequestType() === HttpKernelInterface::MASTER_REQUEST ) {
$request = $event->getRequest();
if ($this->container->get('security.context')->getToken()
&& $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 {
//echo $request->getPathInfo(); exit;
if ($request->isSecure()
&& !in_array($request->getPathInfo(), $httpsPaths)) {
$request->server->set('HTTPS', false);
$request->server->set('SERVER_PORT', 80);
$event->setResponse(new RedirectResponse($request->getUri()));
}
}
}
}
}
Регистрация службы
Сервисы: kernel.listener.forcehttps: класс: Acme\DemoBundle\Listener\ForceHttpsListner теги: - {имя: kernel.event_listener, событие: kernel.request, метод: onKernelRequest } аргументы: [@service_container]
access_control в security.yml
безопасность: контроль доступа: - {путь: ^/_wdt, роль: IS_AUTHENTICATED_ANONYMOUSLY } - {путь: ^ / _ профилировщик, роль: IS_AUTHENTICATED_ANONYMOUSLY} - {путь: ^ / логин $, роль: IS_AUTHENTICATED_ANONYMOUSLY, требуется_канал: https } - {путь: ^/login_check$, роль: IS_AUTHENTICATED_ANONYMOUSLY, требуется_канал: https} - {путь: ^ / зарегистрироваться, роль: IS_AUTHENTICATED_ANONYMOUSLY, канал_требования: https } - {путь: ^ / сброс, роль: IS_AUTHENTICATED_ANONYMOUSLY, канал_требования: https } # Защищенная часть сайта # Этот конфиг требует регистрации для всего сайта и наличия роли администратора для части администратора. # Измените эти правила, чтобы адаптировать их к вашим потребностям - {путь: ^/admin, роль: [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_SUPER_EDITOR] } - {путь: ^/.*, роль: IS_AUTHENTICATED_ANONYMOUSLY}
Вам нужно создать RequestEventListener, запущенный после маршрутизации и безопасности, чтобы обработать его
1) контекст безопасности (посмотрите, полностью ли аутентифицирован пользователь)
2) фактический запрашиваемый маршрут в компоненте маршрутизатора (и сопоставьте его с массивом конфигурации)
затем принять решение или нет принудительно перенаправить на https, если это уже не так.