Précédent   Forum des professionnels en informatique > PHP > Outils > Zend > Zend Framework > Zend_Acl & Zend_Auth
Zend_Acl & Zend_Auth Forum d'entraide pour les composants Zend_Acl & Zend_Auth du Zend Framework (contrôle d'accès, gestion des droits, authentification, etc.). Avant de poster -> Cours Zend_Acl et Zend_Auth.
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 08/04/2011, 11h11   #1
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 998
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 998
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Par défaut ACL : tout en BDD

Bonjour,

Malgré par mal de lecture de différents sujets et tutos, souvent anciens et pas forcément adaptés à ma version de ZF, j'ai du mal à comprendre comment implémenter Zend_Acl correctement dans mon projet.

J'ai modélisé les utilisateurs, leur type (rôle au sens ACL) et même les fonctions de l'application (ressource au sens ACL) dans la BDD selon ce modèle :
utilisateur -1,1----Typer----0,n- type_utilisateur -0,n----Accéder----0,n- fonction

Le rôle d'un utilisateur est donc matérialisé par une clé étrangère faisant référence à son type et les fonctions auxquelles il a accès sont matérialisées par des clés étrangères dans la table associative issue de l'association "Accéder".

Pour le moment, j'ai créé une classe dans le répertoire "library" de mon application qui récupère tout en BDD :
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
<?php
/**
 * library/acl.php
 * Classe d'initialisation du contrôle d'accès aux fonctions de l'application
 * @author Philippe Leménager
 * @version 1.0 - 2011-04-07
 */
class Acl extends Zend_Acl
{
    public function __construct()
    {
        // Chargement des rôles
        $typeuser = new Application_Model_DbTable_Typeutilisateur();
        $tabroles = $typeuser->fetchAll();
 
        foreach($tabroles as $role)
        {
            $this->addRole(new Zend_Acl_Role($role['tu_libelle']));
        }
 
        // Chargement des ressources
        $fonction = new Application_Model_DbTable_Fonction();
        $tabfonctions = $fonction->fetchAll();
 
        foreach($tabfonctions as $ressource)
        {
            $this->addResource(new Zend_Acl_Resource($ressource['fct_libelle']));
        }
 
        // Attribution des droits
        $tabdroits = $typeuser->listeDroits();
 
        foreach($tabdroits as $droit)
        {
            $this->allow($droit['role'], $droit['ressource']);
        }
    }
}
J'avais aussi fait, avant de commencer à étudier les ACL, ce contrôleur d'authentification, à partir d'un tuto :
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
/**
 * application/controllers/AuthController.php
 * Contrôleur de la page d'authentification
 * @author plemenager
 * @version 1.0 - 2011-04-07
 */
 
class AuthController extends Zend_Controller_Action
{
 
    public function init()
    {
    }
 
    /**
     * auth/index
     * Traite la page de connection
     */
    public function indexAction()
    {
        $form = new Application_Form_Login();
        $this->view->title = 'Connexion aux stages master';
        $request = $this->getRequest();
        if ($request->isPost()) 
        {
            if ($form->isValid($request->getPost())) 
            {
                if ($this->_process($form->getValues())) 
                {
                    /*
                     * Authentification réussie, 
                     * redirection vers la page d'accueil selon le type de l'utilisateur
                     */ 
                    $values = $form->getValues();
                    $login = $values['username'];
                    $utilisateur = new Application_Model_DbTable_Utilisateur;
                    $result = $utilisateur->getTypeUtilisateur($login);
                    $typeUtilisateur = $result['tu_libelle'];
 
                    switch ($typeUtilisateur)
                    {
                        case 'Étudiant';
                            $this->_helper->redirector('index', 'accueiletudiant' );
                        break;
 
                        case 'Gestionnaire' :
                            $this->_helper->redirector('index', 'accueilgestionnaire');
                        break;
 
                        case 'Administrateur' :
                            $this->_helper->redirector('index', 'accueilgestionnaire' );
                        break;
                    } // fin switch ($typeUtilisateur)*/
                } // Fin if ($this->_process($form->getValues()))
            } // if ($form->isValid($request->getPost())) 
        } // Fin if ($request->isPost()) 
 
        $this->view->form = $form;
    } // Fin public function indexAction()
 
    protected function _process($values)
    {
        // Get our authentication adapter and check credentials
        $adapter = $this->_getAuthAdapter();
        $adapter->setIdentity($values['username']); 
        $adapter->setCredential($values['password']);
 
        $auth = Zend_Auth::getInstance();
        $result = $auth->authenticate($adapter);
        if ($result->isValid()) 
        {
            $user = $adapter->getResultRowObject();
            unset($user->uti_mot_passe); // Ne pas stocker le mdp en session !
            $auth->getStorage()->write($user);
            return true;
        }
        return false;
    }
 
    protected function _getAuthAdapter()
    {
        $dbAdapter = Zend_Db_Table::getDefaultAdapter();
        $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
 
        $authAdapter->setTableName('th_utilisateur_uti')
                    ->setIdentityColumn('uti_login')
                    ->setCredentialColumn('uti_mot_passe')
                    ->setCredentialTreatment('MD5(?)');
 
        return $authAdapter;
    }
 
    public function logoutAction()
    {
        Zend_Auth::getInstance()->clearIdentity();
        $this->_helper->redirector('index'); // back to login page
    }
}
=> On y voit que, pour le moment, je récupère le libellé du type d'utilisateur en clair afin d'orienter l'utilisateur sur sa page d'accueil, grâce à un simple switch.

Enfin, toujours avant l'étude des ACL, j'avais fait ce genre de truc dans les contrôleurs pour empêcher un utilisateur d'arriver sur une page directement par une URL sans passer par l'authentification :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class AccueiletudiantController extends Zend_Controller_Action
{
 
    // TODO à revoir avec système ACL
    protected $auth; // Identification de l'étudiant connecté.
 
    public function init()
    {
        // Récupération de l'étudiant connecté
        $this->auth = Zend_Auth::getInstance();
        if (! $this->auth->hasIdentity())
        {
            // Si session perdue, on redirige vers la page de connexion
            $this->_helper->redirector('index', 'auth');
        }
 
        // Ajout du helper d'action JQuery autoComplete
        Zend_Controller_Action_HelperBroker::addHelper(
            new ZendX_JQuery_Controller_Action_Helper_AutoComplete()
        );
 
    } // Fin public function init()
Mais je trouve ça lourd de répéter ce code dans chaque contrôleur. De plus, ça ne vérifie pas le rôle de l'utilisateur.

J'ai vu à plusieurs endroits qu'il faut créer un plugin mais, pour commencer, où le mettre dans l'arborescence du projet ? Dans "library" ? Dans "controllers" ? Dans un sous-répertoire "plugins" de "controllers" ? Ailleurs ?

Ensuite, je n'ai pas compris comment on "lance" ce plugin. Par un bout de code dans le Bootstrap.php ? Dans configs/Application.ini ?

Bref, un tuto complet et actualisé à ZF 1.11 serait utile.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/04/2011, 15h44   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 998
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 998
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
J'essaie d'avancer tout seul sur ce sujet mais, comme je le prévoyais, ça ne fonctionne pas du premier coup !

J'ai fait ce plugin que j'ai placé dans controllers/plugins :
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
<?php
/**
 * application/controllers/plugins/Auth.php
 * Plugin pour le contrôle d'accès de l'utilisateur aux fonctions de l'application
 * @author Philippe Leménager
 * @version 1.0 - 2001-04-08
 */
class Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
    private $_auth = null;
    private $_acl = null;
 
    public function __construct($auth, $acl)
    {
        $this->_auth = $auth;
        $this->_acl = $acl;
    }
 
    // Vérifie que l'utilisateur a la permission d'accéder au contrôleur de la page demandée
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        if($this->_auth->hasIdentity())
        {
            // Récupération du type d'utilisateur (= rôle au sens acl)
            $identity = $this->_auth->getIdentity();
            $nom_user = $identity->uti_login;
            $id_role = $identity->uti_id_type_utilisateur;
            $utilisateur = new Application_Model_DbTable_Utilisateur();
            $result = $utilisateur->getTypeUtilisateur($nom_user);
            $nom_role = $result['tu_libelle'];
        } // Fin if($this->_auth->hasIdentity())
 
        $controller = $request->controller;
        $resource   = $this->_acl->has($controller) ? $controller : null;
 
        if (!$this->_acl->isAllowed($nom_role, $resource))
        {
            // Type d'utilisateur non autorisé à accéder à la page
            $request->setControllerName('Auth');
            $request->setActionName('index');
        } // Fin if (!$this->_acl->isAllowed($nom_role, $resource))
    } // Fin function preDispatch
}
J'ai tenté d'initialiser le plugin dans Bootstrap.php :
Code :
1
2
3
4
5
6
    protected function _initAuth()
    {
        $auth = Zend_Auth::getInstance();
        $auth->setStorage(new Zend_Auth_Storage_Session('Auth'));
        $front->registerPlugin(new Plugin_Auth($auth));
    }
J'ai fait comme dans ce message mais qui ne donne qu'un extrait de code.
Et bien sûr, je me tape une belle erreur disant qu'il ne connaît pas la variable $front !
Citation:
Notice: Undefined variable: front in /var/www/html/stagmas/application/Bootstrap.php on line 28

Fatal error: Call to a member function registerPlugin() on a non-object in /var/www/html/stagmas/application/Bootstrap.php on line 28
Comment récupère t-on le front controller ?

EDIT
Trouvé, j'ai maintenant ceci dans le bootstrap :
Code :
1
2
3
4
5
6
7
8
    protected function _initAuth()
    {
        $auth = Zend_Auth::getInstance();
        $auth->setStorage(new Zend_Auth_Storage_Session('Auth'));
        $front = Zend_Controller_Front::getInstance();
        $front->registerPlugin(new Plugin_Auth($auth));
 
    }
Mais j'ai une autre erreur indiquant qu'il ne trouve pas le plugin !
Citation:
Fatal error: Class 'Plugin_Auth' not found in /var/www/html/stagmas/application/Bootstrap.php on line 29
Comme quoi mes questions d'origine sur l'emplacement des éléments n'était pas futile !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2011, 15h32   #3
Invité de passage
 
Inscription : mai 2008
Messages : 2
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 2
Points : 2
Points : 2
Citation:
Mais j'ai une autre erreur indiquant qu'il ne trouve pas le plugin !
Citation:
Fatal error: Class 'Plugin_Auth' not found in /var/www/html/stagmas/application/Bootstrap.php on line 29
Comme quoi mes questions d'origine sur l'emplacement des éléments n'était pas futile !
As-tu pensé à charger ta classe dans ton bootstrap?

Code :
require_once 'controllers/plugins/Auth.php';
Sephyris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2011, 15h37   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 998
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 998
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par Sephyris Voir le message
As-tu pensé à charger ta classe dans ton bootstrap?

Code :
require_once 'controllers/plugins/Auth.php';
J'avais cru comprendre que ZF était capable de trouver les classes tout seul dans son arborescence, et notamment le bootstrap dont c'est un peu le rôle il me semble non ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2011, 17h27   #5
Invité de passage
 
Inscription : mai 2008
Messages : 2
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 2
Points : 2
Points : 2
Tout seul non, par contre, dans le bootstrap, tu peux ajouter ton arborescence aux include_path

Code :
set_include_path('.' . PATH_SEPARATOR . '../library/' . PATH_SEPARATOR . '../application/models/' . PATH_SEPARATOR . get_include_path());
et peut être notamment ton '../application/controllers/plugins/'

à essayer, l'un ou l'autre ou les deux
Sephyris est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h25.


 
 
 
 
Partenaires

Hébergement Web