Quick links: Content - sections - sub sections
EN FR
Quick Search Advanced search
 
Page

  [Opened] [[résolu]] Objet user d'un Driver pour jAuth

Posted by csk on 04/20/2012 20:20

Bonjour à tous,

je suis en train d'étudier l'utilisation du système d'authentification jAuth de Jelix 1.3.1 (jelix 1.3.1 edition dev). Dans mon développement, je suis amené à développer un driver pour jAuth.

D'après la doc, il s'agit d'une classe qui implémente l'interface jIAuthDriver. Dans la doc API de celle-ci, certaines méthodes d'un driver jAuth reçoivent ou retournent un objet $user. Cet objet sera stocké dans une variable de session $_SESSION une fois l'utilisateur authentifié. Il sera utilisé entre 2 actions pour valider la session de l'utilisateur.

Je n'ai malheureusement pas trouvé d'information sur le type de l'objet $user. Je supposais donc qu'il s'agit d'une classe qui serait définie par nos soins et que jAuth n'en lisait pas le contenu directement.

Cependant la méthode "beforeAction" du coordinateur jAuth utilise la méthode jAuth::isConnected et celle-ci tente de lire un attribut "login" de l'objet $user. Or dans la documentation, on ne mentionne pas l'obligation de déclarer cet attribut dans la classe de l'objet $user (ou bien je ne l'ai pas trouvé). La même constatation peut être faite pour les attributs "actif" et "password" utilisés dans le listener onAuthCanLogin du module jAuth.

En outre, considérons que les attributs "login", "actif" et "password" sont déclarés dans ma classe de l'objet $user (classe qui est située dans un de mes modules), la méthode jAuth::isConnected appelé par le coordinateur jAuth, ne pourra quand même pas les lire. En effet, la classe de l'objet $user n'est pas connue à ce moment-là. PHP donne donc un objet "__PHP_Incomplete_Class_Name" et ne sait lire ses attributs. Du coup jAuth::isConnected retourne toujours false.

Je pense que j'ai dû louper une étape dans le principe du fonctionnement du driver... Est-ce que quelqu'un aurait un exemple pour concevoir un driver pour jAuth et un "objet $user" ? Malheureusement le manuel ne donne pas d'exemple exhaustive... (par ailleurs, la page en anglais donne une erreur 404)

Merci d'avance!

  [Opened] Objet user d'un Driver pour jAuth

Reply #1 Posted by foxmask on 04/20/2012 21:54

Bonsoir,

csk a dit :
Bonjour à tous,

je suis en train d'étudier l'utilisation du système d'authentification jAuth de Jelix 1.3.1 (jelix 1.3.1 edition dev).
Dans mon développement, je suis amené à développer un driver pour jAuth.

D'après la doc, il s'agit d'une classe qui implémente l'interface jIAuthDriver. Dans la doc API de celle-ci, certaines méthodes d'un driver jAuth reçoivent ou retournent un objet $user. Cet objet sera stocké dans une variable de session $_SESSION une fois l'utilisateur authentifié. Il sera utilisé entre 2 actions pour valider la session de l'utilisateur.

Je n'ai malheureusement pas trouvé d'information sur le type de l'objet $user. Je supposais donc qu'il s'agit d'une classe qui serait définie par nos soins et que jAuth n'en lisait pas le contenu directement.

$user est du type du driver que l'on utilise, c'est ce qui est dit très subrepticement ici => http://jelix.org/reference/1.3.1/jelix/auth/jAuth.html#updateUser

par exemple si on utilise un driver DB MySQL, on aura :

cDaoRecord_jcommunity_Jx_user_Jx_mysql::__set_state(array(
   'login' => 'foxmask',
   'password' => 'monbomotdepasse',
[...]


Cependant la méthode "beforeAction" du coordinateur jAuth utilise la méthode jAuth::isConnected et celle-ci tente de lire un attribut "login" de l'objet $user. Or dans la documentation, on ne mentionne pas l'obligation de déclarer cet attribut dans la classe de l'objet $user (ou bien je ne l'ai pas trouvé). La même constatation peut être faite pour les attributs "actif" et "password" utilisés dans le listener onAuthCanLogin du module jAuth.

c'est exact !


En outre, considérons que les attributs "login", "actif" et "password" sont déclarés dans ma classe de l'objet $user (classe qui est située dans un de mes modules), la méthode jAuth::isConnected appelé par le coordinateur jAuth, ne pourra quand même pas les lire. En effet, la classe de l'objet $user n'est pas connue à ce moment-là. PHP donne donc un objet "__PHP_Incomplete_Class_Name" et ne sait lire ses attributs. Du coup jAuth::isConnected retourne toujours false.

Je pense que j'ai dû louper une étape dans le principe du fonctionnement du driver...

Avez vous regardé le driver Auth de type "classe" ?

lib/jelix/plugins/auth/class/class.auth.php ? on a une methode createUserObject qui initie les propritété login et password de l'object $user

Est-ce que quelqu'un aurait un exemple pour concevoir un driver pour jAuth et un "objet $user" ? Malheureusement le manuel ne donne pas d'exemple exhaustive... (par ailleurs, la page en anglais donne une erreur 404)

Quelle page ?


Merci d'avance!

Bonne soirée.


@GitHub - Forum HaveFnuBB! powered by Jelix - Le Booster Jelix !

  [Opened] Objet user d'un Driver pour jAuth

Reply #2 Posted by csk on 04/21/2012 20:29

Bonjour foxmask,

tout d'abord, un grand merci pour votre réponse si rapide.

$user est du type du driver que l'on utilise, c'est ce qui est dit très subrepticement ici => http://jelix.org/reference/1.3.1/jelix/auth/jAuth.html#updateUser

Donc si je comprends bien, $user peut être de n'importe quel type (classes, DAO, array, etc...) en fonction du driver. Et c'est là qu'il me semble que la méthode jAuth::isConnected s'avance trop vite en estimant qu'il sait lire à coup sûr "$_SESSION[$config['session_name']]->login" dans jAuth.class.php (avec $_SESSION[$config['session_name']] contenant $user):

class jAuth {
    ...
    public static function isConnected(){
        $config = self::_getConfig();
        return (isset($_SESSION[$config['session_name']]) && $_SESSION[$config['session_name']]->login != '');
    }
    ...

Avez vous regardé le driver Auth de type "classe" ?

En réalité, je m'étais tout d'abord intéressé à ce driver. Mais j'ai besoin d'avoir le mot de passe sous la forme du code hash de login+password, genre:

hash('algorithme',$login.':'.$password)

Cette façon de faire permet d'éviter d'avoir 2 codes de hashage différents pour 2 utilisateurs ayant le même mot de passe.

Malheureusement le driver "classAuthDriver" crypte uniquement le champ de mot passe avec un salt au mieux. Deux utilisateurs différents auront donc le même code hash s'ils ont tous les 2 le même mot de passe. Connaissant le mot de passe de l'un, on pourra se connecter avec le login de l'autre... (je sais, je fais un peu parano...)

C'est pourquoi, je me suis mis dans l'idée d'écrire un driver jAuth qui sera fortement inspiré classAuthDriver. Mais maintenant, je me rends compte que j'aurais très bien pu désactiver le cryptage dans le driver Class et le faire dans ma classe implémentant jIAuthDriverClass (classe qu'on fournit en paramètre dans le fichier de config auth.coord.ini.php).

Néanmoins, le problème reste entier. Car il ne se passe pas à la création de l'objet $user mais bien à sa lecture lorsque le coordinateur jAuth vérifie si un utilisateur est connecté ou non par le biais de la méthode jAuth::isConnected. Dans celle-ci, lorsque $user "sort de sa veille" (à partir de la variable de session $_SESSION), son type d'objet n'est pas forcément connu de PHP.

Lorsqu'on fait un var_dump($user) à moment-là, on se rend compte que PHP le considère comme un "__PHP_Incomplete_Class". Du coup son attribut public $user->login n'est pas accessible et renvoie un null. jAuth::isConnected retourne donc un false alors que l'utilisateur s'est bien authentifié précédemment.

Le problème ne serait pas présent lorsqu'on utilise le driver DAO car $user est un DAO à ce moment-là. La fonction "jelix_autoload" (lib/jelix/init.php) permet à PHP de charger la définition du DAO au moment de sa lecture. Ce qui n'est pas le cas pour ma classe de $user quand on utilise le driver Class, me semble-t-il...

Est-ce un bug ou une mauvaise compréhension de ma part ?

Quelle page ?

Celle-ci: http://docs.jelix.org/en/manual-1.3/authentification/drivers

En bas de page pour le lien "authentication drivers creation" qui pointe vers http://docs.jelix.org/plugins/auth à la place de http://docs.jelix.org/en/manual-1.3/plugins/auth

Très cordialement.

  [Opened] Objet user d'un Driver pour jAuth

Reply #3 Posted by foxmask on 04/23/2012 14:15

bonjour,

Je reponds rapidement,

peut-être que la proposition d'un patch pour que cela soit pris en charge par le framework serait le bienvenue. A défaut d'un patch, au moins ouvir un ticket pour en parler.

cordialement.

ps : je creuserai en détail le reste plus tard qd j'aurai plus de temps devant moi ;)


@GitHub - Forum HaveFnuBB! powered by Jelix - Le Booster Jelix !

  [Opened] Objet user d'un Driver pour jAuth

Reply #4 Posted by csk on 04/23/2012 18:32

Pour le moment, j'ai trouvé une solution bidon mais assez générique pour contourner le problème. De cette façon, je peux continuer mon développement en attendant de trouver une vraie solution.

Pour ça, j'utilise un nouveau coordinateur qui complète le travail de la fonction "jelix_autoload".

/**
 * Extends class autoloading function of Jelix (jelix_autoload)
 */
class myIncluderCoordPlugin implements jICoordPlugin
{
   public $config;
   public function __construct($config)
   {
      $this->config = $config;
      spl_autoload_register('myIncluderCoordPlugin::AutoLoad');
   }
	
   public function beforeAction($params)
   {
      return null;
   }
   public function beforeOutput(){}
   public function afterProcess (){}

   /**
    * Autoload class
    * @param string $classname Name of the class to load.       
    */
   public static function AutoLoad($classname)
   {
      global $gJCoord;
      $includer = $gJCoord->getPlugin('myIncluder');
      if(isset($skinclude->config['JelixClasses'][$classname]))
      {
         jClasses::inc($skinclude->config['JelixClasses'][$classname]);
      }
      elseif(isset($skinclude->config['PhpClasses'][$classname]))
      {
         include_once($skinclude->config['PhpClasses'][$classname]);
      }
   }
}

Fichier de config: index/myIncluder.coord.ini.php

;<?php die(''); ?>
;for security reasons , don't remove or modify the first line

;============= Main parameters
; Classes to include

[JelixClasses]
; Classes defined in your Jelix modules
; Format:
;   classname = "mymodule~classname"
myUserSession = "monModule~myUserSession"

[PhpClasses]
; Generic PHP classes
; Format:
;   classname = "path/to/class.php"

Que ça serve à ceux qui en trouvent l'utilité! :)

  [Opened] Objet user d'un Driver pour jAuth

Reply #5 Posted by laurentj on 04/27/2012 10:46

Bonjour,

Désolé de répondre un peu tard, j'avais des problèmes de PC :)

Si on utilise ses propres classes pour implémenter un utilisateur, il faut bien évidement faire en sorte que la classe soit chargée avant le session_start.

Pour cela, il y a déjà quelque chose de prévu. Dans la configuration, section "sessions", il y a un paramètre loadClasses dans lequel on indique les sélecteurs des classes à charger.

Bref, mettre sa classe dans monmodule/classes/maclasse.class.php, et indiquer

[sessions]
loadClasses = "monmodule~maclasse"

on peut avoir plusieurs classes à charger, en séparant les selecteurs par une virgule

Et sinon, oui, les propriétés login et password sont obligatoires. Il faudrait mieux expliciter ça dans la doc certainement.

Pour ce qui est du chiffrement du mot de passe, il faut en effet définir ça toi-même dans ta classe de driver (qui peut éventuellement hériter d'un driver existant et redéfinir la méthode cryptPassword)

  [Opened] [[résolu]] Objet user d'un Driver pour jAuth

Reply #6 Posted by csk on 04/28/2012 18:36

J'avais lu de fond en comble la documentation sur jAuth sans penser que ma réponse se trouvait dans la page de jClasses (que j'avais déjà lu il y a fort longtemps...).

Un Grand Merci Maître laurentj! :)

 
Page
  1. Objet user d'un Driver pour jAuth