web-dev-qa-db-fra.com

Désactiver le jeton CSRF sur le formulaire de connexion

J'utilise Symfony2.0 et FOSUserBundle et souhaite désactiver le jeton csrf sur mon formulaire de connexion.

J'ai désactivé la protection csrf globalement sur mon site Web dans mon config.yml:

framework:
    csrf_protection:
        enabled:        false

Cela fonctionne bien, aucun champ csrf n’a été ajouté à mes formulaires. Toutefois, cela ne s’applique pas au formulaire de connexion. Sur ce formulaire uniquement, j'obtiens une erreur "Invalid CSRF Token" si je n'inclus pas le jeton dans le formulaire avec:

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

Comment puis-je désactiver le jeton CSRF sur le formulaire de connexion?

15
fkoessler

Si vous accédez simplement à votre fichier security.yml et supprimez le csrf_provider de la directive form_login, vous n'avez pas besoin de mettre à jour la classe d'action ni quoi que ce soit.

17
Daum

Vous pouvez désactiver la protection CSRF dans votre classe de formulaire en définissant 'csrf_protection' => false dans son tableau d'options:

class LoginType extends AbstractType
{
    // ...

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

    // ...

} 

Si vous utilisez FormBuilder pour créer votre formulaire à la place d'une classe AbstractType, vous pouvez passer le tableau d'options comme second paramètre de createFormBuilder() comme ceci:

$form = $this->createFormBuilder($users, array('csrf_protection' => false))
        ->add( ... )
        ->getForm();
28
Juan Sosa

si vous utilisez FOSUserBundle et que vous souhaitez désactiver la protection CSRF uniquement sur le formulaire de connexion, vous devez suivre quelques étapes.

Étape 1) Créez votre propre ensemble d’utilisateurs et votre fichier de contrôleur de sécurité

Afin de remplacer le SecurityController intégré à FOSUserBundle, vous devez d’abord créer votre propre ensemble d’utilisateurs.

Donc, créez un fichier nommé app/src/{YourApp} /UserBundle/Controller/SecurityController.php Vous devez étendre la classe SecurityController d’origine et copier sur la méthode loginAction.

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

Dans la méthode loginAction, commentez ou supprimez ces lignes:

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

Assurez-vous ensuite que rien n'est transmis à afficher pour le jeton CSRF:

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

Étape 2) Désactiver la vérification CSRF dans le pare-feu de Symfony (security.yml)

Assurez-vous de commenter la ligne "csrf_provider:" existante dans security.yml:

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

Étape 3) Remplacer le routage pour le contrôleur de sécurité de FOSUserBundle (routing.yml)

Dans routing.yml, commentez ces lignes:

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

Ajoutez ces lignes en dessous des lignes commentées:

#Over-ride the SecurityController of the FOSUserBundle:
fos_user_security_login:
  path: /login
  defaults:  { _controller: YourAppUserBundle:Security:login }
  methods:  [GET]
  options:
    expose: true

fos_user_security_check:
  path: /login_check
  defaults:  { _controller: FOSUserBundle:Security:check }
  methods:  [POST]
  options:
    expose: true

fos_user_security_logout:
  path: /logout
  defaults:  { _controller: FOSUserBundle:Security:logout }
  methods:  [GET]
  options:
    expose: true

Remarque 1: Je lui ai seulement demandé d'utiliser la méthode loginAction à partir de votre SecurityController personnalisé. Les deux autres méthodes vont à la classe parente (pas sûr si cela fait une différence).

Note 2: Vous avez besoin de la partie "expose: true"! Sinon, vous obtiendrez une erreur JavaScript du bundle de routage fos js.

Ça devrait le faire!

1
Jay Sheth

Je devais outrepasser SecurityController loginAction de FOSUserBundle où le formulaire de connexion est instancié.

J'ai remplacé:

$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,
    ));

avec:

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,
    ));
0
fkoessler