30 votes

Besoin de conseils pour démarrer avec Zend ACL

Je suis actuellement en train de travailler sur un site qui requiert une ACL et comme je suis à l'aide de Zend, il fait sens pour moi de faire usage de leur classe ACL, mais j'ai peu à zéro idée de comment faire cela. J'ai lu la doc, mais il me troublait de plus...en gros je veux faire, c'est de mettre en place deux groupes d'utilisateurs par exemple "normal" et "admin", normal les utilisateurs peuvent accéder à toutes les pages qui ont un contrôleur qui n'est pas admin alors que les admin peuvent évidemment accéder à l'admin du contrôleur pages.

J'ai beaucoup de questions:

  1. Comment puis-je le configurer?
  2. Dois-je le lancer à travers un DB ou de la config.ini?
  3. Où dois-je placer mon ACL.php?
  4. Comment puis-je écrire un tel script?
  5. Comment puis-je l'appeler, est-ce fait dans l'Index?.

Je serais très heureux si vous me guider vers un site web ou un bon tutoriel.

38voto

Marek Janouch Points 366

J'ai implémenté chose de similaire n'y a pas longtemps. Concept de base qui suit d'un exemple de code.

J'ai créé mon propre configAcl.php fichier qui est chargé dans le fichier de bootstrap, dans mon cas c'est index.php. Voici comment il serait selon votre cas:

$acl = new Zend_Acl();

$roles  = array('admin', 'normal');

// Controller script names. You have to add all of them if credential check
// is global to your application.
$controllers = array('auth', 'index', 'news', 'admin');

foreach ($roles as $role) {
    $acl->addRole(new Zend_Acl_Role($role));
}
foreach ($controllers as $controller) {
    $acl->add(new Zend_Acl_Resource($controller));
}

// Here comes credential definiton for admin user.
$acl->allow('admin'); // Has access to everything.

// Here comes credential definition for normal user.
$acl->allow('normal'); // Has access to everything...
$acl->deny('normal', 'admin'); // ... except the admin controller.

// Finally I store whole ACL definition to registry for use
// in AuthPlugin plugin.
$registry = Zend_Registry::getInstance();
$registry->set('acl', $acl);

Un autre cas est que si vous souhaitez autoriser l'utilisateur normal seulement "liste" action sur tous vos contrôleurs. C'est assez simple, vous devez ajouter la ligne comme ceci:

$acl->allow('normal', null, 'list'); // Has access to all controller list actions.

Ensuite, vous devez créer un nouveau plugin qui prend en charge les informations d'identification de vérifier automatiquement quand il ya une demande pour certains d'action du contrôleur. Cette vérification a lieu dans preDispatch() méthode qui est appelée avant chaque appel à l'action du contrôleur.

Voici AuthPlugin.php:

class AuthPlugin extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $loginController = 'auth';
        $loginAction     = 'login';

        $auth = Zend_Auth::getInstance();

        // If user is not logged in and is not requesting login page
        // - redirect to login page.
        if (!$auth->hasIdentity()
                && $request->getControllerName() != $loginController
                && $request->getActionName()     != $loginAction) {

            $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');
            $redirector->gotoSimpleAndExit($loginAction, $loginController);
        }

        // User is logged in or on login page.

        if ($auth->hasIdentity()) {
            // Is logged in
            // Let's check the credential
            $registry = Zend_Registry::getInstance();
            $acl = $registry->get('acl');
            $identity = $auth->getIdentity();
            // role is a column in the user table (database)
            $isAllowed = $acl->isAllowed($identity->role,
                                         $request->getControllerName(),
                                         $request->getActionName());
            if (!$isAllowed) {
                $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');
                $redirector->gotoUrlAndExit('/');
            }
        }
    }
}

Les dernières étapes sont le chargement de votre configAcl.php et enregistrer le AuthPlugin dans un fichier de bootstrap (probablement index.php).

require_once '../application/configAcl.php';

$frontController = Zend_Controller_Front::getInstance();
$frontController->registerPlugin(new AuthPlugin());

Donc, c'est le concept de base. Je n'ai pas tester le code ci-dessus (copier-coller et de réécriture juste pour la vitrine but), il n'est donc pas à l'épreuve des balles. Juste pour donner une idée.

MODIFIER

Pour la clarté. Le code ci-dessus dans AuthPlugin supposons que la somme de l'identité de l'objet est rempli avec les données de l'utilisateur ("rôle" de la colonne dans la base de données). Cela pourrait être fait dans le processus d'ouverture de session comme ceci:

[...]
$authAdapter = new Zend_Auth_Adapter_DbTable($db);
$authAdapter->setTableName('Users');
$authAdapter->setIdentityColumn('username');
$authAdapter->setCredentialColumn('password');
$authAdapter->setIdentity($username);
$authAdapter->setCredential(sha1($password));
$authAdapter->setCredentialTreatment('? AND active = 1');
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
    $data = $authAdapter->getResultRowObject(null, 'password'); // without password
    $auth->getStorage()->write($data);
[...]

2voto

axiom82 Points 62

Cette solution peut s'avérer être la plus simple de mise en œuvre de Zend_Acl.

Exemple:

class UserController extends Zend_Controller_Action {

    public function preDispatch(){

        $resource = 'user_area';
        $privilege = $this->_request->getActionName();
        if (!$this->_helper->acl($resource, $privilege)) $this->_redirect();

    }

}

Zend/Controller/Action/Helper/Acl.php

class Zend_Controller_Action_Helper_Acl extends Zend_Controller_Action_Helper_Abstract {

    protected $acl;
    protected $role;

    protected function getAcl(){

        if (is_null($this->acl)){

            $acl = new Zend_Acl();

            $acl->addResource(new Zend_Acl_Resource('user_area'));
            $acl->addResource(new Zend_Acl_Resource('customer_area'), 'user_area');
            $acl->addResource(new Zend_Acl_Resource('web_area'));

            $acl->addRole(new Zend_Acl_Role('guest'));      
            $acl->addRole(new Zend_Acl_Role('user'), 'guest');

            $acl->allow('guest', 'web_area');
            $acl->allow('guest', 'user_area', array(
                'forgot-password',
                'login'
            ));
            $acl->allow('user', 'user_area');
            $acl->allow('customer', 'customer_area');

            $this->acl = $acl;

        }

        return $this->acl;

    }

    protected function getRole(){

        if (is_null($this->role)){

            $session = new Zend_Session_Namespace('session');
            $role = (isset($session->userType)) ? $session->userType : 'guest';
            $this->role = $role;

        }

        return $this->role;

    }

    public function direct($resource, $privilege = null){

        $acl = $this->getAcl();
        $role = $this->getRole();
        $allowed = $acl->isAllowed($role, $resource, $privilege);
        return $allowed;

    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X