0
$this->add ( new Zend_Acl_Resource ( 'index' ) );
$this->addRole ( new Zend_Acl_Role ( 'guest' ) );
$this->allow('guest', 'index','view');

そして私はこの状態で問題を抱えています

if (! $this->_acl->isAllowed ( $role, $resource, $action )){ 
    ... redirect to access denied
}
  • ゲストは、Contollerインデックスとアクションビューにアクセスできます。
  • しかし、彼がurl / index / view2と入力すると、アクションview2が存在しないため、エラーページにリダイレクトされるはずです。
  • しかし、この条件は、彼がアクションビューのためにolnyを許可されていることを示しています。したがって、彼をエラーページにリダイレクトするのではなく、アクセスを拒否します

この問題をどのように解決できますか?

4

3 に答える 3

3

リソース(アクション)がaclに存在するかどうかを確認できます。

if(!$this->_acl->has($resource) || $this->_acl->isAllowed($role, $resource, $action))

それ以外の場合は、デフォルトで単純に拒否できます。次に、存在しないアクションをチェックすると、aclはデフォルトでfalseを返します。
存在しないアクションがコントローラーから呼び出されたかどうかを単に検出したい場合は、コントローラーの__callメソッドを使用できます。

より具体的な解決策については、acl-checkを実行する場所、aclの設定方法などの詳細情報を提供する必要があります。

コントローラに存在しないアクションをキャッチする例:

My_Controller extends Zend_Controller_Action
{
    __call($method, $args)
    {
        throw new Exception("Action does not exist"); // This is done by default
        // Just do whatever you want to do in this function (like redirecting)
    }
}

とにかく、これは魔法の関数がなくてもErrorhandlerPluginで行うことができます。エラーページにリダイレクトするだけなので、実際には注意が必要です。リソース(またはアクション)が見つからないため、aclチェックで例外がスローされないように注意してください。チェックを行う場所に応じて、これを行う可能性がいくつかありますが、すべてのコントローラーが1つのリソースであり、すべてを追加すると仮定すると、これは問題にはなりません。

于 2010-11-11T11:40:14.100 に答える
1

フロントコントローラープラグインの事前ディスパッチでACLを呼び出します

public function preDispatch(Zend_Controller_Request_Abstract $request) {
    if ($this->_auth->hasIdentity ()) {
        $rights = $this->_auth->getIdentity ()->rights;
        if ($rights == 2) {
            $role = 'admin';
        } elseif ($rights == 1) {
            $role = 'user';
        } else {
            $role = 'guest';
        }
    } else {
        $role = 'guest';
    }
    $controller = $request->controller;
    $action = $request->action;
    $module = $request->module;
    $resource = $controller;
    if ($this->_acl->has ( $resource )) {
        if (! $this->_acl->isAllowed ( $role, $resource, $action )) {
            if (! $this->_auth->hasIdentity ()) {
                //redirect to login
                $module = $this->_noauth ['module'];
                $controller = $this->_noauth ['controller'];
                $action = $this->_noauth ['action'];            
            } else {
                //redirect to access denied
                $module = $this->_noacl ['module'];
                $controller = $this->_noacl ['controller'];
                $action = $this->_noacl ['action'];
            }
            $request->setModuleName ( $module );
            $request->setControllerName ( $controller );
            $request->setActionName ( $action );
        }
    } else {
        //controller not found
        $module = ('default');
        $controller = ('error');
        $action = ('not-found');
        $request->setModuleName ( $module );
        $request->setControllerName ( $controller );
        $request->setActionName ( $action );
    }           
}
于 2010-11-13T08:25:47.653 に答える
0

私はNotAllowed例外をスローすることによってそれを行います。

if (! $this->_acl->isAllowed ( $role, $resource, $action )){ 
    throw new YourNotAllowedException('some error message');
}

次に、エラーコントローラーでこの例外を処理します。

if ($error->exception instanceof NotAllowed) {
   // manual forward setting request params 
   // (url remains the same, but user sees the login page)
}

標準の例外は通常どおり処理されます。

于 2010-11-11T17:17:13.190 に答える