Zend:View帮助程序中的ACL逻辑

时间:2010-02-03 22:42:40

标签: zend-framework zend-acl

背景资料:

我在admin模块中,并在modules/admin/views/helpers/AdminPanel.php中创建了一个视图助手。我有一个布局插件,强制我的视图使用admin/views/layouts/default.phtml中的布局。

我正在尝试访问我的ACL对象以确定用户是否在视图助手的上下文中有资源,然后通过解析configs / admin-nav.xml或者确定是否返回管理面板html或根本不回报任何东西。

我在我的管理员布局中调用它是这样的:

<?php echo $this->AdminPanel(); ?>

并且我需要访问acl对象的类代码是空白的:

class My_View_Helper_AdminPanel extends Zend_View_Helper_Abstract {

public function AdminPanel() {}

}

我试过了:

$acl = Zend_Controller_Action_HelperBroker::getStaticHelper('acl');

但这可能不是我想要的,因为它会强制默认模块的views/layouts/default.phtml加载并发生错误。

这是我的全局引导程序文件:

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    private $_acl = null;
    private $_auth = null;

    protected function _initDoctype() {
    $this->bootstrap('view');
    $view = $this->getResource('view');
    $view->setEncoding('UTF-8');
    $view->doctype('HTML4_STRICT');
    }

    protected function _initAutoload() {
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace('KG_');
    $resourceLoader = new Zend_Loader_Autoloader_Resource(
        array(
        'basePath' => APPLICATION_PATH,
        'namespace' => '',
        'resourceTypes' => array(
            'form' => array(
            'path' => 'forms/',
            'namespace' => 'Form_'
            ),
            'model' => array(
            'path' => 'models/',
            'namespace' => 'Model_'
            )
        )
        ));
    return $autoloader;
    }

    protected function _initAclAuth() {
    $this->_acl = new Model_Acl;
    $this->_auth = Zend_Auth::getInstance();
    }

    protected function _initNav() {
    $this->bootstrap('layout');
    $layout = $this->getResource('layout');
    $view = $layout->getView();
    $config = new Zend_Config_Xml( APPLICATION_PATH . '/configs/nav.xml', 'mainNav');
    $navigation = new Zend_Navigation( $config );

    $fc = Zend_Controller_Front::getInstance();
    $fc->registerPlugin( new KG_Controller_Plugin_Acl( $this->_acl, $this->_auth ) );

    $role = $this->_auth->getStorage()->read()->role;

    if ( !$role ) {
        $role = 'guest';
    }

    $view->navigation( $navigation )->setAcl( $this->_acl)->setRole( $role );
    }


    protected function _initEncoding() {
    $fc = Zend_Controller_Front::getInstance();
    $response = new Zend_Controller_Response_Http;
    $response->setHeader('Content-Type','text/html;charset=utf-8', true);
    $fc->setResponse($response);
    }

}

1 个答案:

答案 0 :(得分:2)

您的KG_Controller_Plugin_Acl插件应该关注访问逻辑,而不是您的视图。如果用户无权访问该资源,则应该将用户错误或重定向到其他位置。

应在控制器内设置布局。最好在init()方法中使用:

$this->_helper->layout->setLayout();

看起来你遵循了与Zend_Acl相同或类似的教程。我发布了我的插件以供参考,其中包括从插件中处理访问控制的逻辑:

class App_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{

    protected $_auth = null;
    protected $_acl = null;

    public function __construct(Zend_Auth $auth, Zend_Acl $acl)
    {
        $this->_auth = $auth;
        $this->_acl = $acl;
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        if ($this->_auth->hasIdentity()) {
            $identity = $this->_auth->getIdentity();
            $role = $identity->acl_role;
        } else {
            $role = 'guest';
        }

        // Mapping to determine which Resource the current
        // request refers to (really simple for this example!)
        $resource = $request->controller;
        $privilege = $request->action;


        if (!$this->_acl->has($resource)) {
            $resource = null;
        }

        // ACL Access Check
        if (!$this->_acl->isAllowed($role, $resource, $privilege)) {
            if ($this->_auth->hasIdentity()) {
                // authenticated, denied access, forward to /error/permissions
                $request->setModuleName('default');
                $request->setControllerName('error');
                $request->setActionName('permissions');
            } else {
                // not authenticated, forward to login form
                $request->setModuleName('default');
                $request->setControllerName('auth');
                $request->setActionName('login');
            }
        }
    }
}