2012-07-29 71 views
1

我有一個web項目,其中一些訪問決策都依賴於頁面本身(如/logout這應僅可見於用戶登錄),有些是依賴於動態模型對象(例如/article/delete/1234,我們必須檢查1234是否由登錄用戶編寫,或者他是否是管理員)。Zend_Acl中的規則同時基於MVC和波輪機型

現在,我正面臨着如何將兩者結合在一起的問題。無論我怎樣努力,我可以不依賴任何單獨兩個:

  • 有些不使用任何型號,所以我不能設置任何模型規則
  • 在另一方面,我不能創建動態斷言模塊化方法,因爲Comment只是一個comment而不是一個default/comment。 A Comment不限於默認模塊,它也可以在管理模塊中使用。

With 模塊化ACL我想檢查每個頁面是否允許用戶訪問它,例如,

if (!$acl->isAllowed($user, 'default/secrets', 'mysecrets')) { 
    $this->forward('auth', 'login'); 
    $this->setDispatched(false); 
} 

而且隨着動態斷言如果有人可以編輯一個特定的模型對象我檢查。

// $comment has a method getResourceId() returning 'comment' 
if ($acl->isAllowed($user, $comment, 'delete')) { 
    // display a link for deletion 
} 

當然,這將是很好如果

  • 刪除某個評論,並
  • 檢查訪問/評論/刪除/ ????

頁將是相同的,但我想這是不可能的,我就必須建立兩個規則:

$acl->allow('member', 'default/comment', 'delete'); 
$acl->allow('member', 'comment', 'delete', new Acl_Assert_CommentAuthor()); 
$acl->allow('admin', 'comment', 'delete'); 

現在,這似乎不完美的我,因爲這可能導致重複工作在某些情況下。

有沒有更好的方法來解決這個問題?或者是至少創造這樣一個連貫的命名方案的唯一方法:mvc:default/commentmodel:comment

+0

我不明白「默認」是什麼。 – conradfr 2012-07-30 08:58:28

+0

'default'是Zend Framework中的默認模塊。我的應用程序中的其他模塊是'admin','vocabulary'。這是從應用程序的發展。如果我有'articles'和'messages',會更好,但現在這兩個都是'default'的一部分。 – Aufziehvogel 2012-07-30 14:52:40

回答

0

路上,我做到了,那結果限制自定義SQL查詢,插入/刪除/修改SQL之前檢查功能

和那麼ACL插件,我寫了檢查,許可和使用這些5桌

acl_groups 
acl_permession 
acl_permession_groups 
acl_permession_risource 
acl_risource 

代碼:

class Abc_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract 
{ 

    /** 
    * Return whether a given request (module-controller-action) exists 
    * 
    * @param Zend_Controller_Request_Abstract $request Request to check 
    * @return boolean Whether the action exists 
    */ 
    private function _actionExists(Zend_Controller_Request_Abstract $request) 
    { 
     $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher(); 

     // Check controller 
     if (!$dispatcher->isDispatchable($request)) { 
      return false; 
     } 

     $class = $dispatcher->loadClass($dispatcher->getControllerClass($request)); 
     $method = $dispatcher->formatActionName($request->getActionName()); 

     return is_callable(array($class, $method)); 
    } 



    public function preDispatch(Zend_Controller_Request_Abstract $request) 
    { 

     // fetch the current user 

     $controller = $request->controller; 
     $action = $request->action; 

     $logger = Zend_Registry::get('log'); 



     //prima controlla se sei autenticato e poi controlla se l'azione esiste, cosi non esponi il sito 
     $auth = Zend_Auth::getInstance(); /* @var $auth Zend_Auth */ 
      if($auth->hasIdentity()) { 


       if(! $this->_actionExists($request))//l'azione non esiste? 
       { 
        $request->setControllerName('error'); 
        $request->setActionName('pagenotfound'); 
         $logger->notice(" IP: ". $_SERVER['REMOTE_ADDR']. " http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]. " ?" .http_build_query($_REQUEST)); 
        return ; 
       } 

       $allowed = Abc_Action_Helper_CheckPermission::checkPermission($controller, $action); 

       if ($allowed !== 1) 
       { 
        $request->setControllerName('error'); 
        $request->setActionName('noauth'); 
       } 
       //fine azione esiste 
      }else{ 
            $request->setControllerName('user'); 
       $request->setActionName('login'); 
       return ; 
      } 


    }//fine preDispatch 

} 

可以再加入你的代碼(我爲了簡短而省略)記住請求並在登錄後重定向你。