How can I force authenticated user to HTTPS in Symfony2 after fully authentication only?

StackOverflow https://stackoverflow.com//questions/25051797

  •  21-12-2019
  •  | 
  •  

Question

I need to use https in Symfony 2.2 but only if user is fully authenticated.

Was it helpful?

Solution

Just got solution using onKernalRequest event listener.

My onKernelRequest event service :

<?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()));
                }

            }

        }

    }
}

Register service

services:
    kernel.listener.forcehttps:
        class: Acme\DemoBundle\Listener\ForceHttpsListner
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [ @service_container ]

access_control in security.yml

security:
    access_control:
        - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/_profiler, role: IS_AUTHENTICATED_ANONYMOUSLY }        
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/admin, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_SUPER_EDITOR] }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

OTHER TIPS

You'll need to create a RequestEventListener, fired after routing and security, to handle in it

1) the security context (see if user is fully authenticated)
2) the actual asked route in the router component (and match it with a configuration array)

to then decide or not to force redirect to https if not already the case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top