【问题标题】:Need guidance to start with Zend ACL需要指导以开始使用 Zend ACL
【发布时间】:2010-10-07 10:31:28
【问题描述】:

我目前正在开发一个需要 ACL 的网站,并且由于我正在使用 Zend,因此使用他们的 ACL 类对我来说是有意义的,但我对如何做到这一点几乎没有任何想法。我已经阅读了文档,但它让我更加困惑......基本上我想做的就是设置两个用户组,例如“正常”和“管理员”,普通用户可以访问所有具有非管理员控制器的页面,而管理员显然可以访问管理员控制器页面。

我有很多问题:

  1. 如何设置?
  2. 我应该通过 DB 还是 config.ini 运行它?
  3. 我在哪里放置我的 ACL.php?
  4. 如何编写这样的脚本?
  5. 然后我该如何调用,这是在索引中完成的吗?。

如果您能引导我访问一个网站或一个好的教程,我将不胜感激。

【问题讨论】:

    标签: php zend-framework authentication user-controls acl


    【解决方案1】:

    玩这个结构。从数据库中获取角色和资源并将其保存在会话中或任何缓存中。

    【讨论】:

      【解决方案2】:

      这个解决方案可能被证明是 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;
      
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        不久前我实现了类似的东西。示例代码中遵循基本概念。

        我创建了自己的 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 并在引导文件(可能是 index.php)中注册 AuthPlugin。

        require_once '../application/configAcl.php';
        
        $frontController = Zend_Controller_Front::getInstance();
        $frontController->registerPlugin(new AuthPlugin());
        

        所以这是基本概念。我没有测试上面的代码(复制粘贴和重写只是为了展示)所以它不是防弹的。只是提供一个想法。

        编辑

        为了清楚起见。 AuthPlugin 中的上述代码假设 $identity 对象填充了用户数据(数据库中的“角色”列)。这可以在登录过程中完成,如下所示:

        [...]
        $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);
        [...]
        

        【讨论】:

        • 这在我的网站结构中的什么位置? APPLICATION 控制器模型视图 PUBLIC css 图片 js flash LIBRARY zend 有什么建议吗?
        • configAcl.php 可以在您的应用程序目录中的任何位置,它仅用于包含在 index.php 中。 AuthPlugin 应该在您的库中——因此 Zend 能够自动加载它并且您不必使用 require_once。 [...] 之间的最后一条语句取决于您的登录过程...
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-27
        • 1970-01-01
        相关资源
        最近更新 更多