2013-03-07 18 views
14

Sto usando Symfony2.0 e FOSUserBundle e desidero disabilitare il token csrf sul mio modulo di login.Disabilita token CSRF sul modulo di login

Ho disabile la protezione CSRF a livello globale sul mio sito nel mio config.yml:

framework: 
    csrf_protection: 
     enabled:  false 

Questo funziona bene, non c'è nessun campo csrf aggiunto le mie forme. Tuttavia, questo non si applica al modulo di accesso. Su questo modulo solo, ottengo un errore "non valido CSRF token" se non si include il token nel modulo con:

<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" /> 

Come posso disattivare il token CSRF nel modulo di accesso?

+1

Perché vuoi farlo? – j0k

+0

Poiché il mio cliente desidera che il modulo di accesso venga convalidato, indipendentemente da quanto tempo l'utente è rimasto nella pagina di accesso. Inoltre, personalmente non penso che una protezione CSRF sia necessaria per questo particolare sito web. –

risposta

15

Se basta andare al file security.yml e rimuovere il csrf_provider dalla direttiva form_login, non c'è bisogno di aggiornare l'azione classe o qualsiasi cosa.

+0

Bene, questa dovrebbe essere la risposta accettata .. –

27

È possibile disabilitare la protezione CSRF nella classe form impostando 'csrf_protection' => false nella sua gamma opzioni:

class LoginType extends AbstractType 
{ 
    // ... 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class'  => 'Acme\UserBundle\Entity\User', 
      'csrf_protection' => false 
     ); 
    } 

    // ... 

} 

Nel caso in cui si utilizza FormBuilder per creare il modulo, invece di una classe AbstractType, è possibile passare la matrice opzioni come secondo parametro per createFormBuilder() come questo:

$form = $this->createFormBuilder($users, array('csrf_protection' => false)) 
     ->add(...) 
     ->getForm(); 
+0

Il problema è che non ho una classe LoginType. Dovrei estendere la classe Symfony2 LoginType solo per impostare la proprietà csrf_protection su false? Non c'è un modo più semplice? –

+0

Ho aggiornato la mia risposta. Spero che sia d'aiuto. –

+0

Sì, mi ha aiutato a capire che dovevo esaminare il SecurityController di FOSUserBundle per impostare il csrf su false. Ho pubblicato la mia risposta con ulteriori dettagli su come procedere. +1 –

0

ho dovuto override FOSUserBundle's SecurityController loginAction cui è istanziare il form di login.

ho sostituito:

$csrfToken = $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate'); 

return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login.html.'.$this->container->getParameter('fos_user.template.engine'), array(
     'last_username' => $lastUsername, 
     'error'   => $error, 
     'csrf_token' => $csrfToken, 
    )); 

con:

return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login.html.'.$this->container->getParameter('fos_user.template.engine'), array(
     'last_username' => $lastUsername, 
     'error'   => $error, 
     'csrf_token' => false, 
    )); 
1

se si utilizza FOSUserBundle e si desidera disabilitare la protezione CSRF solo nel modulo di accesso, ci sono alcuni passaggi da seguire.

Fase 1) Creare il proprio fascio utente & il file Security Controller

Per eccesso di cavalcare il SecurityController che è costruito in FOSUserBundle, è necessario prima creare il proprio pacchetto utente.

Quindi, creare un file chiamato app/src/{} YourApp /UserBundle/Controller/SecurityController.php Si dovrebbe estendere la classe SecurityController originale, e copiare il metodo loginAction

use FOS\UserBundle\Controller\SecurityController as SecurityControllerOrig; 
class SecurityController extends SecurityControllerOrig 
{ 
    public function loginAction(Request $request) 
    { 
    } 
} 

All'interno del loginAction metodo, come commento, o rimuovere queste righe:

$csrfToken = $this->container->has('form.csrf_provider') 
     ? $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate') 
     : null; 

quindi assicurarsi che nulla è passato a vedere per il token CSRF:

return $this->renderLogin(array(
     'last_username' => $lastUsername, 
     'error'   => $error, 
     'csrf_token' => false, 
    )); 

Punto 2) Disattivare CSRF il check-in del firewall di Symfony (security.yml)

Assicurarsi di commentare la "csrf_provider:" esistente linea nella sicurezza.yml:

firewalls: 
     main: 
      pattern: ^/ 
      form_login: 
       provider: fos_userbundle 
       #csrf_provider: form.csrf_provider 

Fase 3) Ignorare il percorso per il controllore di sicurezza di FOSUserBundle (routing.yml)

In routing.yml, commentare queste righe:

fos_user_security: 
    resource: "@FOSUserBundle/Resources/config/routing/security.xml" 
    options: 
     expose: true 

aggiungere queste righe al di sotto della righe commentate:

Nota 1: ho solo chiesto di utilizzare il metodo loginAction da il tuo SecurityController personalizzato. Gli altri due metodi vanno alla classe genitore (non è sicuro se faccia la differenza).

Nota 2: è necessaria la parte "expose: true"! Altrimenti, si otterrà un errore JavaScript dal bund di instradamento di fos js.

Questo dovrebbe farlo!