Нужно руководство, чтобы начать с Zend ACL - PullRequest
30 голосов
/ 13 февраля 2009

В настоящее время я работаю над сайтом, который требует ACL, и, поскольку я использую Zend, для меня имеет смысл использовать их класс ACL, но у меня практически нет идеи о том, как это сделать. Я прочитал документы, но это смутило меня еще больше ... в основном все, что я хочу сделать, - это создать две группы пользователей, например. «Обычный» и «Администратор», обычные пользователи могут получить доступ ко всем страницам, на которых есть контроллер, который не является администратором, в то время как администратор, очевидно, может получить доступ к страницам контроллера администратора.

У меня много вопросов:

  1. Как мне это настроить?
  2. Должен ли я запустить его через БД или config.ini?
  3. Где я могу разместить свой ACL.php?
  4. Как мне написать такой скрипт?
  5. Как мне тогда позвонить, сделано ли это в Указателе?

Я был бы очень признателен, если бы вы указали мне сайт или хороший учебник.

Ответы [ 3 ]

38 голосов
/ 13 февраля 2009

Я реализовал подобную вещь не так давно. Основная концепция приведена в примере кода.

Я создал свой собственный файл configAcl.php, который загружается в файл начальной загрузки, в моем случае это index.php. Вот как это будет в вашем случае:

$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);

Другой случай, если вы хотите разрешить обычному пользователю только «список» действий на всех ваших контроллерах. Это довольно просто, вы бы добавили строку так:

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

Далее вы должны создать новый плагин, который автоматически проверяет учетные данные при запросе какого-либо действия контроллера. Эта проверка выполняется в методе preDispatch (), который вызывается перед каждым вызовом действия контроллера.

Вот 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('/');
            }
        }
    }
}

Последние шаги - загрузка файла configAcl.php и регистрация AuthPlugin в файле начальной загрузки (возможно, index.php).

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

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

Так что это основная концепция. Я не тестировал код выше (копировать, вставлять и переписывать только для демонстрации), поэтому он не пуленепробиваемый. Просто чтобы дать идею.

EDIT

Для ясности. Код выше в AuthPlugin предполагает, что объект $ identity заполнен пользовательскими данными (столбец «role» в базе данных). Это можно сделать в процессе входа в систему следующим образом:

[...]
$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);
[...]
2 голосов
/ 25 августа 2014

Играть с этой структурой. получить роль и ресурс из базы данных и сохранить его в сеансе или для любого кэширования. enter image description here

2 голосов
/ 19 ноября 2013

Это решение может оказаться самой простой реализацией Zend_Acl.

Пример:

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;

    }

}
...