Как я могу принудить аутентифицированного пользователя к 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, если это уже не так.

Другие вопросы по тегам