Zend:视图助手中的 ACL 逻辑

发布于 2024-08-20 01:00:36 字数 2780 浏览 5 评论 0原文

背景信息:

我在我的 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);
    }

}

Background information:

I'm in my admin module, and I created a view helper in modules/admin/views/helpers/AdminPanel.php. I have a layout plugin that forces my view to use the layout in admin/views/layouts/default.phtml.

I'm trying to access my ACL object to determine whether or not the user has resources in the context of a view helper, and then determine whether to return the admin panel html by parsing a configs/admin-nav.xml or not return anything at all.

I'm calling it in my admin layout like so:

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

And the class code which is blank, which I need to access the acl object in:

class My_View_Helper_AdminPanel extends Zend_View_Helper_Abstract {

public function AdminPanel() {}

}

I tried this:

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

But this probably isn't what I'm looking for as it forces the default module's views/layouts/default.phtml to load and errors occur.

Here's my global bootstrap file:

<?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);
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奶茶白久 2024-08-27 01:00:36

您的 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');
            }
        }
    }
}

Your KG_Controller_Plugin_Acl plugin should be taking care of the access logic, not your view. If the user doesn't have access to the resource, you should error out or redirect the user to somewhere else.

The layout should be set within the controller. Preferably in the init() method with:

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

It looks like you followed the same or a similar tutorial as I did for Zend_Acl. I'm posting my plugin for reference, which includes the logic to handle access control from within the plugin:

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');
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文