Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > symfony
symfony Forum d'entraide sur le framework PHP symfony. Avant de poster : cours symfony et FAQ symfony
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/06/2011, 09h57   #1
Invité de passage
 
Homme
Inscription : juin 2011
Messages : 9
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : juin 2011
Messages : 9
Points : 2
Points : 2
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 :
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 :
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.))
maxime.b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/06/2011, 22h14   #2
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
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à.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/06/2011, 14h30   #3
Invité de passage
 
Homme
Inscription : juin 2011
Messages : 9
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : juin 2011
Messages : 9
Points : 2
Points : 2
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)
maxime.b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/06/2011, 08h58   #4
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
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.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/06/2011, 09h01   #5
Invité de passage
 
Homme
Inscription : juin 2011
Messages : 9
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : juin 2011
Messages : 9
Points : 2
Points : 2
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)
maxime.b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2012, 10h54   #6
Membre à l'essai
 
Femme
Étudiant
Inscription : mai 2010
Messages : 39
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2010
Messages : 39
Points : 24
Points : 24
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 :
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 :
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 :
1
2
 
 $this->context->getUser()->signIn($user);
alors déjà moi j'aurai mis :
Code :
1
2
 
 $this->getContext()->getUser()->signIn($user);
mais ça ne marche pas non plus
misswatson est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2012, 11h50   #7
Membre chevronné
 
Avatar de kenny.kev
 
Homme
Inscription : janvier 2007
Messages : 574
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Indre et Loire (Centre)

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

Informations forums :
Inscription : janvier 2007
Messages : 574
Points : 688
Points : 688
Envoyer un message via MSN à kenny.kev
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.
kenny.kev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2012, 12h39   #8
Membre à l'essai
 
Femme
Étudiant
Inscription : mai 2010
Messages : 39
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2010
Messages : 39
Points : 24
Points : 24
l'erreur est la suivante :
Code :
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.
misswatson est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2012, 13h07   #9
Membre à l'essai
 
Femme
Étudiant
Inscription : mai 2010
Messages : 39
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2010
Messages : 39
Points : 24
Points : 24
Citation:
Envoyé par misswatson Voir le message
l'erreur est la suivante :
Code :
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
misswatson est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h08.


 
 
 
 
Partenaires

Hébergement Web