0

すでにZendAuthを使用しているZendFrameworkにACLを実装しました。

いくつかのコントローラーへのアクセスを許可したいので、次のように試しました。

$roleGuest = new Zend_Acl_Role('guest');
$this->addRole($roleGuest);

$this->addRole(new Zend_Acl_Role('supplier'));
$this->addRole(new Zend_Acl_Role('admin'));

$this->add(new Zend_Acl_Resource('Articles'));
$this->add(new Zend_Acl_Resource('Index'));

$this->deny();

$this->allow('supplier', 'Articles');

$this->allow('admin', null);

しかし、サプライヤーであるユーザー(彼は本当に:))はコントローラーの記事を見ることができません。私は何が間違っているのですか?

手伝ってくれてありがとう。

BR frgtv10

4

2 に答える 2

0

最善の解決策は、プラグインを作成して次のようなものを書くことだと思います

    class Application_Controller_Plugin_AclManager extends Zend_Controller_Plugin_Abstract
{
   public function preDispatch(Zend_Controller_Request_Abstract $Request)
   {
      $AclManager = new Zend_Acl();

      $AclManager->addRole(new Zend_Acl_Role('Guest'));
      $AclManager->addRole(new Zend_Acl_Role('Supplier'), 'Guest');

      $AclManager->addResource(new Zend_Acl_Resource('controller1'));
      $AclManager->addResource(new Zend_Acl_Resource('controller2'));
      $AclManager->addResource(new Zend_Acl_Resource('controller3'));

      $AclManager->allow('Guest', 'controller1', 'index');
      $AclManager->allow('Supplier', 'controller2');
      $AclManager->allow('Supplier', 'controller3');

それはうまくいくでしょう。さらに、あなたは書くことができます

if (! $AclManager->isAllowed(USER_ROLE, $Request->getControllerName(), $Request->getActionName()))
      {
         $this->getResponse()->setRedirect(SOME_URL_TO_REDIRECT);
      }
于 2011-09-13T19:04:29.303 に答える
0

user707795からのアプローチは良いです。Pike_Reflection_Resourceを使用してリソースを構築し、リソースを自動的に定義します。まだ完全には文書化されていませんが、使用法は非常に簡単です。

Pikeライブラリの最新バージョンをダウンロードします http://code.google.com/p/php-pike/

次に、Zend_Aclを拡張するACLクラスを作成します。

<?php
class Application_Acl extends Zend_Acl
{

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->_addRoles();
        $this->_addResources();
        $this->_setAuthorization();
    }

    /**
     * Adds roles to ACL
     */
    protected function _addRoles()
    {
        /**
         * Get your roles from the application config here or the database like below (Doctrine2)
         */
//        $repository = $this->_em->getRepository('BestBuy\Entity\Usergroup');       

        $roles = array('guest', 'admin', 'moderator');

        foreach($roles as $role) {
            $this->addRole(new Zend_Acl_Role(strtolower($role)));            
        }               
    }

    /**
     * Adds resources to ACL
     * 
     * Here are resources added to the ACL. You don't have to do this manually 
     * because Pike_Reflection_Resource will search automaticly in your controller
     * directories to define which actions there are and adds every resource as:
     * modulename_controller_actionname all lowercase.
     */
    public function _addResources()
    {
        $resourceReflection = new Pike_Reflection_Resource();
        $resources = $resourceReflection->toFlatArray('default');

        foreach ($resources as $resource => $humanValue) {
            $this->addResource(new Zend_Acl_Resource($resource));
        }
    }

    /**
     * Sets authorization
     */
    public function _setAuthorization()
    {   

        //$permissions = $this->_em->getRepository('BestBuy\Entity\Permission')->findAll();
        /**
         * I retrieve my permissions here from the database but you could receive the
         * from the roles attribute too:
         */
        $resourceReflection = new Pike_Reflection_Resource();
        $resources = $resourceReflection->toArray('default');

        foreach ($resources as $moduleName => $controllers) {
            foreach($controllers as $controllerName=>$actions) {
                foreach($actions as $actionName=>$action) {

                    $resourceName = sprintf('%s_%s_%s',
                        strtolower($moduleName),
                        strtolower($controllerName),
                        strtolower($actionName)
                    );                    

                    if(isset($action['roles'])) {
                        foreach($action['roles'] as $role) {
                            if ($this->hasRole($role) && $this->has($resourceName)) {
                                $this->allow($role, $resourceName);
                            }                            
                        }
                    }
                }
            }
        }                     
    }
}
?>

次に、上記のようなフロントコントローラープラグインを設定します。

    <?php
class Application_Controller_Plugin_Authorization extends Zend_Controller_Plugin_Abstract
{
    /**
     * Request
     *
     * @var Zend_Controller_Request_Abstract
     */
    protected $_request;

    /**
     * ACL
     *
     * @var Buza_Acl
     */
    protected $_acl;

    /**
     * Called before Zend_Controller_Front enters its dispatch loop.
     *
     * @param  Zend_Controller_Request_Abstract $request
     * @return void
     */
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)        
    {        
    $this->_request = $request;
    $this->_acl = new Application_Acl();

    Zend_Registry::set('acl', $this->_acl);

    $this->_checkAuthorization();
    }

    /**
     * Checks if the current user is authorized
     */
    protected function _checkAuthorization()
    {
    $allowed = false;
    $currentResource = sprintf('%s_%s_%s',
        strtolower($this->_request->getModuleName()),
        strtolower($this->_request->getControllerName()),
        strtolower($this->_request->getActionName())
    );

    if(Zend_Auth::getInstance()->hasIdentity()) {
        $user = Zend_Auth::getInstance()->getIdentity());

        $identityRole = strtolower($user->getRole()); //make sure you implement this function on your user class/identity!
    } else {
        $identityRole = 'guest';
    }

    if ($this->_acl->hasRole($identityRole) && $this->_acl->has($currentResource)) {
        if ($this->_acl->isAllowed($identityRole, $currentResource)) {
            $allowed = true;
        }           
    }        

    if ($allowed !== true) {                        
        throw new Zend_Controller_Exception('No permission', 403);            
    }        
    }

}
    ?>

最後に、コントローラー/アクションで、次のように権限を定義します。

<?php
class IndexController extends Zend_Controller_Action {
    /**
     * @human Some description for the permissions of this action
     * @roles guest|admin|moderator
     */
    public function indexAction() {
    }

    /**
     * @human Only for admins!
     * @roles admin
     */
    public function secretAction() {
    }
}
?>

このアプローチは、小規模なアプリケーションに最適でセットアップされています。アプリケーションのインターフェースで許可されるアクションを定義するアプリケーションの場合は、rolesタグを残して、データベースのアクセス許可を取得する必要があります。

以下のコードはテストされていませんが、いくつかのレビューを行うことで機能し、コードで権限を制御できることに注意してください。

于 2011-09-13T19:29:46.073 に答える