Cet article s’inscrit à la suite du précèdent billet : Authentification & Autorisation avec Zend AMF.
Zend_Amf_Adobe_Auth est une classe livré avec Zend 1.10. Elle peut être utilisée comme service d’authentification pour un serveur Zend_Amf_Server. Le soucis, c’est que cette classe fonctionne conjointement avec un fichier XML réputé statique.
Voici donc le code d’une classe qui permet l’authentification d’un utilisateur AMF via la base de données.
Sachant que nous développons cela pour offrir des services AMF, cette classe utilisera la logique métier implémentée au sein des services.
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 | class Auth_AmfDatabase extends Zend_Amf_Auth_Abstract { protected $_acl; protected $_users = array(); public function __construct() { $this->_acl = new Zend_Acl(); $oServiceRole = new Service_Role (); $oRoles = $oServiceRole->fetchAll ( ); foreach ( $oRoles as $oRole ) $this->_acl->addRole ( new Zend_Acl_Role( $oRole->title ) ); } public function getAcl() { return $this->_acl; } public function authenticate() { if (empty($this->_username) || empty($this->_password)) { require_once 'Zend/Auth/Adapter/Exception.php'; throw new Zend_Auth_Adapter_Exception('Username/password should be set'); } $oServiceUser = new Service_User (); $oUser = $oServiceUser->authentication ( $this->_username, $this->_password ); if ( null == $oUser ) { return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null, array('Username and / or Password not found') ); } else { $id = new stdClass(); $id->role = $oUser->role->code; $id->name = $oUser->username; return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $id); } } } |
Le constructeur récupère l’ensemble des rôles existants en base de données pour peupler l’objet ACL.
La méthode authenticate va vérifier le couple Login / Password, et en cas de succès va retourner un objet Zend_Auth_Result contenant lui même un objet standard.
Cet objet standard doit avoir une propriété role et name, le rôle contiendra l’identifiant que vous avez définit dans vos autorisations ACL. Le name devra contenir le login de votre utilisateur.
Cette classe a été inspirée par Zend_Amf_Adobe_Auth. N’hésitez pas à l’adapter pour vos propres besoins.
bonjour,
pour reprendre mon cas de figure évoqué lors du précédent article (appli Flex multi bases) dois je invoquer Auth_AmfDatabase dans chaque appel de méthodes recevant en param mes identifiants de base ? N’est il pas possible de le faire une bonne fois pour toute dans le constructeur de mes services ?
Si j’ai bien compris, il est impossible de définir un setAuth sur un serveur AMF dans un projet multi bases ?
Je sais c’est pas forcément très clair…
Merci
Je n’ai pas tout compris :p
Dans mon cas, j’ai une passerelle unique pour AMF. Cette passerelle utilise Zend_Amf_Server, qui lui même utilise Auth_AmfDatabase. A ce serveur j’associe une liste de Services ainsi que des ACL. C’est tout..
Pour le coup, ta question trouvera réponse au sein des différents didacticiels sur Zend + AMF.
ah ok c’est le serveur qui lance Auth_AmfDatabase ?
Je veux pas polluer les coms mais je viens peut être de trouver une piste que je vais creuser
Merci en tout cas de ton implication
Tout est coté serveur 😉
Bon courage à toi, et bonne chance.
je croyais avoir trouvé mais non ^^
comment mettre en place un adapter de base de données sur le server sachant que je ne connais la base à utiliser que dans mes services ?
Rhaa je tourne en rond là ^^
Merci Thomas,
c’est exactement ce que je cherchais à faire ! Sauf que je n’arrive pas à le mettre en place… Est-ce qu’il te serait possible de mettre en partage tous les fichiers utilisés pour bien voir le lien entre tout ça (ton gateway.php, tes classes Service_Role…) ? Je sais j’en demande beaucoup, mais ce que tu proposes est tellement intéressant qu’on a envi de tout comprendre
Désolé, je ne peut pas tout publier. Le reste du code est privée, il va falloir imaginer vos propres solutions.
@ZendAdept, tu remarquera que dans l’exemple de l’article, je n’utilise absolument aucune connexion directe à la base de données.. Cela se fait via l’intermédiaire des Services.
Services qui eux-même réalisent la connexion à la base de données via Doctrine.
Je comprends bien…
Pouvez-vous juste m’expliquer le fonctionnement et l’utilité de la fonction authentication dans la classe Service_User ?
@kyfr4n, voici le prototype de la fonction authentication :
Service_User::authentication (String login, String password) UserDTO.
Elle vérifie simplement l’existence du couple login / password et retourne un objet UserDTO en cas de correspondance, null sinon.
Cela permet de valider l’authentification pour la classe Auth_AmfDatabase.
Amusez-vous à ajouter des grains de sel à ce niveau pour augmenter la sécurité 😉
Oui en effet Thomas 😉
je pense que je peux m’en sortir finalement
Par contre tu parles des grains de sel mais de mon côté j’en génère un pour chaque utilisateur à l’inscription (stockés dans une table users), c’est possible de gérer l’authentification lors du login en introduisant mon champs salt ? Je pense que oui et le lien zend ici http://framework.zend.com/manual/1.10/fr/zend.auth.adapter.dbtable.html semble me le confirmer mais je voudrais en être certain ?
Mais qu’est ce qui ce passe ici ??? Mais c’est la ruée ! C’est le délire !
@ZendAdept, tu es libre de faire ce que tu souhaite.. Techniquement, je ne vois aucune contre indication.
Ok merci Thomas
Sinon pour mon système d’authentification je suis toujours paumé ^^
En effet ce serait simple de faire un :
$server->setAuth($authAdapter);
avec un adapter base de données, sauf que je connais pas forcément sur le moment la base à utiliser. Exemple : quand l’utilisateur n’est pas encore connecté…Après avec un getter je dois pouvoir m’en tirer mais avant…
@ZendAdept,
A ce niveau, c’est un soucis lié à ton infrastructure.. Seule la force te permettra de t’en sortir 😉
Oui mais le serveur est le point d’entrée et il lance les méthodes qui vont justement me définir mon adapter avec les setters donc comment le connaitre à l’avance ?
Force est de constater que la force ne m’accompagne pas ^^
Merci 1000 fois Thomas, j’ai réussi à faire mon principe d’authentification !!!
J’avais un problème, c’était qu’une fois mon authentification faite, Zend_Auth->getIdentity() ne me renvoyait jamais rien. Je pensais que la persistance d’identité se faisait automatiquement, mais à priori non…
Pour ceux qui rencontrent ce problème, il faut juste penser à ajouter :
$authInstance = Zend_Auth::getInstance();
$authInstance->getStorage()->write($identity);
au moment de l’identification. J’espère ne pas avoir raconté de bêtises.
Merci encore Thomas pour ces très précieuses informations.
Ouf j’y suis enfin parvenu
@kyfr4n : merci tu m’as bien aidé j’avais le même soucis 😉
@Thomas : merci grandement pour tes conseils et ta patience 😉
J’avais le problème que je n’appelais pas directement la méthode authenticate(). Donc j’avais toujours “Unauthenticated access not allowed”. En rajoutant l’appel de cette méthode dans mon constructeur c’est bon. Par contre Thomas, je pourrais savoir comment et où tu appèles cette méthode ? Fais tu quelque chose de ce genre à la place ?
$auth = new Auth_AmfDatabase();
$auth->authenticate();
$server->setAuth($auth);
Merci
@ZendAdept, L’appel est effectué automatiquement par Zend_AMF_Server.. Regarde de plus près cette classe, tu vas apprendre de nombreuses choses.
Essai de te débrouiller un peu tout seul 😉
Merci, c’est exactement ce que je cherchais à faire depuis plusieurs jours et votre solution fonctionne.
Stéphane