2009-02-13 46 views
30

我目前正在研究一個需要ACL的網站,因爲我正在使用Zend,對我來說使用它們的ACL類是有道理的,但我對於如何做的事情一無所知這個。我已經閱讀了文檔,但它讓我更加困惑......基本上我想要做的就是設置兩個用戶組,例如「正常」和「管理員」,普通用戶可以訪問所有具有非管理員控制器的頁面,而管理員可以明顯訪問管理員控制器頁面。需要指導,以Zend ACL開頭

我有很多問題:

  1. 如何設置呢?
  2. 我應該通過數據庫還是config.ini來運行它?
  3. 我在哪裏放置我的ACL.php?
  4. 我該如何編寫這樣的腳本?
  5. 我該怎麼打電話,這是在索引中完成的嗎?

我非常感謝,如果你指導我一個網站或一個很好的教程。

回答

38

不久前我實現了類似的東西。基本概念如下代碼示例。

我創建了我自己的configAcl.php文件,它被加載到bootstrap文件中,在我的情況下是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()); 

所以這是基本概念。我沒有測試上面的代碼(複製粘貼和重寫只是爲了展示目的),所以它不是防彈的。只是想提供一個想法。

編輯

對於清晰度。上面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); 
[...] 
+0

這是在我的網站結構? 應用 控制器 車型 意見 PUBLIC CSS 圖像0​​JS 閃光燈 庫 的Zend 什麼建議嗎? – Udders 2009-02-16 09:23:24

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 /控制器/動作/助手/ 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; 

    } 

} 
2

玩這個結構。從數據庫獲取角色和資源,並將其保存在會話或任何緩存中。 enter image description here