How can I force authenticated user to HTTPS in Symfony2 after fully authentication only?
-
21-12-2019 - |
Question
I need to use https in Symfony 2.2 but only if user is fully authenticated.
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