IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Authentification par CAS, problème CSRF [1.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 15
    Par défaut Authentification par CAS, problème CSRF
    Bonjour,

    J'ai réalisé une petite application pour me faire la main sur symfony après avoir lu "Practical symfony" et je bloque depuis un moment sur le problème suivant.

    Après avoir travaillé sur les fonctionnalités, j'ai intégré la gestion des utilisateurs, l'authentification et la gestion des droits avec le plugin sfDoctrineGuardPlugin (V1.0.4). Jusque là tout va bien.

    Mais j'ai besoin d'utiliser un CAS pour gérer l'authentification. J'ai récupéré sur le web une classe qui permet cette authentification (https://wiki.jasig.org/display/CASC/Symfony+CAS+Client). Depuis, je peux toujours m'authentifier et accéder à l'application mais plus aucun de mes formulaires ne fonctionne : "csrf token: CSRF attack detected."

    J'ai donc comparé mes formulaires selon que je m'authentifie avec le plugin Symfony ou par le CAS.

    Dans les 2 cas le jeton _csrf_token est présent. Seule différence remarquée...
    Avec le CAS, mon jeton est toujours différent d'un formulaire à un autre.
    Sans le CAS, mon jeton est toujours le même.

    Le problème vient sans doute de là mais je ne connais pas bien le fonctionnement de la protection CSRF et je ne sais pas comment corriger ce problème.

    J'espère que vous pourrez m'aiguiller pour corriger ce problème

    Merci


    Le code de la classe d'authentification par le CAS.
    /lib/sfCASRequiredFilter.class.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    class sfCASRequiredFilter extends sfBasicSecurityFilter
    {
     
     
      public function execute ($filterChain)
      {
      	if ( $this->isFirstCall() || !$this->getContext()->getUser()->isAuthenticated() ) {
     
            phpCAS::client(CAS_VERSION_2_0,$this->getParameter('server_domain'), $this->getParameter('server_port'), $this->getParameter('server_path'));
     
            phpCAS::forceAuthentication();
     
            $user_ldap = phpCAS::getUser();
     
    		// Témoin d'authentification de symfony ! 
    		//$this->getContext()->getUser()->signInWithCas($user_ldap);
            $this->getContext()->getUser()->setAuthenticated(true);
     
            // Recherche si l'utilisateur authentifié est bien dans la base de données !
            $userTable = Doctrine_Core::getTable('SfGuardUser');
      		$user = $userTable->findOneByUsername($user_ldap);
      		// fait le lien entre l'utilisateur authentifié et ces données dans la base de l'application
            $this->context->getUser()->signIn($user); 
     
            $this->getContext()->getUser()->setAttribute('username', $user_ldap, 'cas');
            $this->getContext()->getUser()->addCredential('username_'.$user_ldap);
           	$this->getContext()->getUser()->setAttribute('username_cas', $user_ldap);
     
        }
     
        # if not initially authorized, sfBasicSecurityFilter sets $controller->forward(sfConfig::get('sf_login_module'), sfConfig::get('sf_login_action'));
        # so we re-dispatch since we are already authorized
        # copied from sfFrontWebController's dispatch()
        $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} configs are ' . sfConfig::get('sf_login_module') . '/' . sfConfig::get('sf_login_action'));
        if ($this->getContext()->getModuleName() == sfConfig::get('sf_login_module')
                && $this->getContext()->getActionName() == sfConfig::get('sf_login_action')) {
     
            $request    = $this->getContext()->getRequest();
            $moduleName = $request->getParameter('module');
            $actionName = $request->getParameter('action');
     
            $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} forwarding to ' . $moduleName . '/' . $actionName);
            $this->getContext()->getController()->forward($moduleName, $actionName);
        }
     
        // Execute next filter in the chain
        $filterChain->execute();
      }
    }
    Configuration du CAS dans le fichier filters.yml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    rendering: ~
     
    cas_required:
      enabled: %SF_CAS_REQUIRED% 
      class: sfCASRequiredFilter
      param:
        server_domain: le.domaine
        server_port: le.port
        server_path: le.path
     
    security:  ~
     
    # insert your own filters here
     
    cache:     ~
    execution: ~
    ((%SF_CAS_REQUIRED% est définit dans le settings.yml.))

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    L'idée en CSRF est qu'il y a, dans chaque formulaire, génération d'un jeton pour l'utilisateur, ce qui permet de vérifier que l'utilisateur est bien le même qui répond que celui qui a reçu le form, ce qui permet d'éviter de nombreuse attaques.

    De tête, le jeton est stocké dans la session utilisateur. A priori, ton système d'authentification perturbe le fonctionnement normal de la classe myUser (dans lib de l'application). Cherches de ce côté là.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 15
    Par défaut
    Merci pour la réponse.

    Je n'ai toujours pas résolu le problème mais j'ai découvert pourquoi mon jeton change a chaque formulaire. Le jeton est généré avec l'identifiant de session et c'est cet identifiant de session qui change à chaque fois.

    Reste à voir pourquoi ma session n'est pas conservée et comment y remédier.
    (je vais sans doute continuer ma fouille de la classe myUser demain)

  4. #4
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Comme dirait Firefox "Hum, c'est embarrassant !"

    J'ai un peu l'impression que ton authentification se refait à chaque appel de page.

    Autre inconvénient, si tu changes systématiquement de session, tu n'as plus la persistance des données user d'une session à l'autre, ce qui va compliquer le fonctionnement de symphony.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 15
    Par défaut
    Retour sur bug à tête reposée. Et erreur de débutant !
    Et comme le ridicule ne tue pas, je poste pour clore cette discussion.

    L'identifiant de session change à chaque page, et pour cause...
    la ligne $this->getContext()->getUser()->setAuthenticated(true); est appelée à chaque fois.
    Il suffisait donc de modifier le test qui s'applique à cette partie du code.

    Merci pour ta réponse et pour les nombreuse autres du forum qui m'ont bien aidées!
    (on a posté en meme temps)

  6. #6
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 62
    Par défaut
    Citation Envoyé par maxime.b Voir le message
    Bonjour,

    J'ai réalisé une petite application pour me faire la main sur symfony après avoir lu "Practical symfony" et je bloque depuis un moment sur le problème suivant.

    Après avoir travaillé sur les fonctionnalités, j'ai intégré la gestion des utilisateurs, l'authentification et la gestion des droits avec le plugin sfDoctrineGuardPlugin (V1.0.4). Jusque là tout va bien.

    Mais j'ai besoin d'utiliser un CAS pour gérer l'authentification. J'ai récupéré sur le web une classe qui permet cette authentification (https://wiki.jasig.org/display/CASC/Symfony+CAS+Client). Depuis, je peux toujours m'authentifier et accéder à l'application mais plus aucun de mes formulaires ne fonctionne : "csrf token: CSRF attack detected."

    J'ai donc comparé mes formulaires selon que je m'authentifie avec le plugin Symfony ou par le CAS.

    Dans les 2 cas le jeton _csrf_token est présent. Seule différence remarquée...
    Avec le CAS, mon jeton est toujours différent d'un formulaire à un autre.
    Sans le CAS, mon jeton est toujours le même.

    Le problème vient sans doute de là mais je ne connais pas bien le fonctionnement de la protection CSRF et je ne sais pas comment corriger ce problème.

    J'espère que vous pourrez m'aiguiller pour corriger ce problème

    Merci


    Le code de la classe d'authentification par le CAS.
    /lib/sfCASRequiredFilter.class.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    class sfCASRequiredFilter extends sfBasicSecurityFilter
    {
     
     
      public function execute ($filterChain)
      {
      	if ( $this->isFirstCall() || !$this->getContext()->getUser()->isAuthenticated() ) {
     
            phpCAS::client(CAS_VERSION_2_0,$this->getParameter('server_domain'), $this->getParameter('server_port'), $this->getParameter('server_path'));
     
            phpCAS::forceAuthentication();
     
            $user_ldap = phpCAS::getUser();
     
    		// Témoin d'authentification de symfony ! 
    		//$this->getContext()->getUser()->signInWithCas($user_ldap);
            $this->getContext()->getUser()->setAuthenticated(true);
     
            // Recherche si l'utilisateur authentifié est bien dans la base de données !
            $userTable = Doctrine_Core::getTable('SfGuardUser');
      		$user = $userTable->findOneByUsername($user_ldap);
      		// fait le lien entre l'utilisateur authentifié et ces données dans la base de l'application
            $this->context->getUser()->signIn($user); 
     
            $this->getContext()->getUser()->setAttribute('username', $user_ldap, 'cas');
            $this->getContext()->getUser()->addCredential('username_'.$user_ldap);
           	$this->getContext()->getUser()->setAttribute('username_cas', $user_ldap);
     
        }
     
        # if not initially authorized, sfBasicSecurityFilter sets $controller->forward(sfConfig::get('sf_login_module'), sfConfig::get('sf_login_action'));
        # so we re-dispatch since we are already authorized
        # copied from sfFrontWebController's dispatch()
        $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} configs are ' . sfConfig::get('sf_login_module') . '/' . sfConfig::get('sf_login_action'));
        if ($this->getContext()->getModuleName() == sfConfig::get('sf_login_module')
                && $this->getContext()->getActionName() == sfConfig::get('sf_login_action')) {
     
            $request    = $this->getContext()->getRequest();
            $moduleName = $request->getParameter('module');
            $actionName = $request->getParameter('action');
     
            $this->getContext()->getLogger()->debug('{sfCASRequiredFilter} forwarding to ' . $moduleName . '/' . $actionName);
            $this->getContext()->getController()->forward($moduleName, $actionName);
        }
     
        // Execute next filter in the chain
        $filterChain->execute();
      }
    }
    Configuration du CAS dans le fichier filters.yml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    rendering: ~
     
    cas_required:
      enabled: %SF_CAS_REQUIRED% 
      class: sfCASRequiredFilter
      param:
        server_domain: le.domaine
        server_port: le.port
        server_path: le.path
     
    security:  ~
     
    # insert your own filters here
     
    cache:     ~
    execution: ~
    ((%SF_CAS_REQUIRED% est définit dans le settings.yml.))
    Salut !
    je sais bien que cette discussion remonte à longtemps, mais il se trouve que je cherche a faire la même chose que toi, j'ai récupérer la classe sfCASRequiredFilter sur internet et j'essaye de la modifier de façon à faire la liaison entre l'utilisateur authentifié et celui présent dans ma base de données, j'ai essayé plein de truc mais ça marche pas, j'essaye de faire comme toi, mais ça plante à ce niveau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     $this->context->getUser()->signIn($user);
    alors déjà moi j'aurai mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     $this->getContext()->getUser()->signIn($user);
    mais ça ne marche pas non plus

  7. #7
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    Tu es un peu vague, qu'est ce qui marche pas.

    Quel est l'erreur que tu as ?

    PS : Tu aurais dût créer un nouveau topic et mettre celui-ci en lien car il est résolu, il y a des chances que peux de personne n'y prête attention.

  8. #8
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 62
    Par défaut
    l'erreur est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Call to undefined method myUser::signIn.
    Ce que je veux faire, c'est faire le lien entre l'utilisateur authentifié et ses informations dans la base de l'applications.

  9. #9
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2010
    Messages : 62
    Par défaut
    Citation Envoyé par misswatson Voir le message
    l'erreur est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Call to undefined method myUser::signIn.
    Ce que je veux faire, c'est faire le lien entre l'utilisateur authentifié et ses informations dans la base de l'applications.
    Au fait j'ai compris pour quoi il reconnait pas la méthode signIn(), c'est une méthode propre au plugin sfDoctrineGuardPlugin(), mais moi je ne l'utilise pas, mais j'ai toujours pas de solution à mon problème

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/03/2009, 14h33
  2. Problème d'authentification par root à l'ouverture de session Fedora
    Par marcandre dans le forum RedHat / CentOS / Fedora
    Réponses: 3
    Dernier message: 04/02/2009, 17h39
  3. Réponses: 3
    Dernier message: 05/11/2007, 11h58
  4. problème d'authentification par FORM
    Par volivi dans le forum ASP.NET
    Réponses: 2
    Dernier message: 23/07/2007, 09h38
  5. Réponses: 4
    Dernier message: 18/05/2006, 09h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo