2011-11-30 6 views
6

Voglio forzare l'utente a utilizzare HTTPS anziché HTTP, ma solo dopo l'autenticazione. L'unica opzione che ho trovato è forzare HTTPS su base controller/metodo. Gli utenti anonimi dovrebbero usare solo HTTP.Symfony2, passa a HTTPS dopo l'autenticazione

Come impostare force-HTTPS solo per utenti autenticati e forzare a NON utilizzare HTTPS per utenti non autenticati in tutti i controller nel mio pacchetto?

Ancora: non si tratta di disabilitare HTTPS per la pagina di autorizzazione.

Desidero utilizzare tutti gli stessi controller per utenti autenticati e non autenticati ma forzare quelli che hanno effettuato l'accesso a utilizzare HTTPS e quelli che non utilizzano HTTP. In pratica aggiungi il requisito per HTTPS per TUTTI i controller quando l'utente è autenticato.

Questa domanda è specifica per Symfony 2. Voglio farlo usando i meccanismi di Symfony. So come rilevare questa cosa, ma interromperà i collegamenti Twig. Symfony può passare automaticamente a HTTPS, voglio solo sapere come farlo sulla base del ruolo per utente, non in base al controller.

+0

Hai una domanda? – JJJ

+1

Non utilizzare HTTPS per l'autenticazione è una decisione BAD. Significa che i dati inviati/ricevuti sono in testo normale e chiunque abbia accesso a qualsiasi macchina nel percorso tra il client e il server sarà in grado di leggere i pacchetti e raccogliere le credenziali (utente, pass, cookie, ecc.). C'è un motivo speciale per non utilizzare SSL per l'autenticazione? – jweyrich

+2

@jweyrich Questa non è la domanda. Voglio che l'utente usi https per tutte le pagine successive dopo l'autorizzazione (che è esterna btw) e disabilita https per gli utenti non autorizzati. –

risposta

10

Si potrebbe pensare che il controller di accesso avrebbe fatto questo per noi:

access_control: 
    - { role: ROLE_USER, requires_channel: https } 
    - { role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: http } 

Ma, no ... credo che questa sarebbe una caratteristica molto carino.

In questo caso, siamo in grado di incidere qualcosa insieme con una richiesta di ascoltatore che utilizzano gli eventi del kernel:

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

definire il vostro ascoltatore in config.yml sotto servizi:

myapp.request.listener: 
    class: MyApp\MyBundle\EventListener\RequestListener 
    tags: 
     - { name: kernel.event_listener, event: kernel.request } 

Vedi Symfony Internals per dettagli su eventi e simili.

+1

È possibile controllare il nostro pacchetto che consente comportamenti automatici come forzare ssl per gli utenti registrati, senza fornire un 403 se accedono al sito senza https: https://github.com/nelmio/NelmioSecurityBundle – Seldaek

2

In Symfony 2.0.11 viene visualizzato un errore di reindirizzamento. Per risolvere questo ho commentato le seguenti righe nell'ascoltatore.

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