9

私は自分のアプリケーションをZendFrameworkに基づいています。私はZend_Auth認証に使用していZend_Aclますが、率直に言って、私が見た例は私のニーズに対して単純すぎるか、私を混乱させるため、私にとってうまくいくかどうかはわかりません。

私は自分のアプリケーションの要素をリソースとして考えており、これらのリソースは特権を持つことができます。リソース特権を含むロールは動的に定義され、ユーザーに割り当てられます。この情報を正規化されたテーブルに保存しています。

  1. ユーザーには役割があります
  2. ロールは複数のリソースを持つことができます
  3. リソースは複数の特権を持つことができます

ロールは、実際には階層のないリソース特権の単なるコレクションです。リソースの例は「ページ」です。誰でもページを表示できますが、認証されたユーザーは、ページで他のことを行うために「追加」、「編集」、または「削除」権限が必要になります。

これはZendACLと噛み合っていますか?私はACLを私にとって問題を引き起こすような方法で考えていますか?


私の解決策

Typeonerrorが功を奏しますが、これが私の具体的な解決策です。

Zend_Acl現在のユーザーの役割のみをロードするため、使用法を簡素化するために拡張しました。

class My_Acl extends Zend_Acl
{
    protected $_role_id;

    public function setRole($role_id)
    {
        $this->_role_id = $role_id;
        return $this->addRole($role_id);
    }

    public function getRole()
    {
        return $this->_role_id;
    }

    public function deny($resource, $privilege)
    {
        return parent::deny($this->_role_id, $resource, $privilege);
    }

    public function allow($resource, $privilege)
    {
        return parent::allow($this->_role_id, $resource, $privilege);
    }

    public function isAllowed($resource, $privilege)
    {
        return parent::isAllowed($this->_role_id, $resource, $privilege);
    }
}

resourceACLにデータを入力するために、、、privilegeおよびrole_id列を返すクエリを実行します。role_idユーザーのロールにその特権がない場合、結果セットの列はnullになります。

$acl = new My_Acl();

$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    $userInfo = $auth->getStorage()->read();
    $acl->setRole($userInfo->role_id);
} else {
    $acl->setRole('');
}

// QUERY HERE

foreach ($privileges as $privilege) {
    if (!$acl->has($privilege['resource'])) {
        $acl->addResource($privilege['resource']);
    }
    if (is_null($privilege['role_id'])) {
        $acl->deny($privilege['resource'], $privilege['privilege']);
    } else {
        $acl->allow($privilege['resource'], $privilege['privilege']);
    }
}
4

1 に答える 1

10

それがまさにその仕組みであり、あなたはそれについて正確に考えていると思います。リソースを追加してから特権を追加して、特定のユーザーロールがリソースにアクセスできるようにすることができます。たとえば、私のCMSには、「開発者」、「管理者」、「ユーザー」がいます。以下のコードでは、一般的なアクセスを追加してから、特定のユーザーのアクセスからいくつかのアクションと特定のメソッドを削除します。もちろん、これは私のアプリケーションにかなり固有ですが、基本的には、auth-> getIdentity()(または同様のもの)からユーザーの役割を取得してから、データベースから役割/リソースを追加する必要があります。

<?php

/**
 * @author     Benjamin Borowski <ben.borowski@typeoneerror.com>
 * @copyright  Copyright (c) Typeoneerror Studios http://typeoneerror.com
 * @version    $Id$
 * @category   Typeoneerror
 * @package    Acl
 */

/**
 * Defines basic roles and resources for an application as
 * well as a Content Management System (CMS).
 *
 * Zend_Acl provides a lightweight and flexible access control list
 * (ACL) implementation for privileges management.
 *
 * {@inheritdoc}
 *
 * @author     Benjamin Borowski <ben.borowski@typeoneerror.com>
 * @copyright  Copyright (c) Typeoneerror Studios http://typeoneerror.com
 * @version    $Id$
 * @category   Typeoneerror
 * @package    Acl
 */
class Typeoneerror_Acl extends Zend_Acl
{
    /**
     * Constructor function.
     *
     * Creates basic roles and resources and adds them to Acl.
     *
     * {@inheritdoc}
     *
     * @return Typeoneerror_Acl
     */
    public function __construct()
    {
        //---------------------------------------
        // ROLES
        //---------------------------------------

        $this->_addRole("guest")
             ->_addRole("member", "guest")
             ->_addRole("admin", "member")
             ->_addRole("developer", "admin");

        //---------------------------------------
        // FRONT-END RESOURCES
        //---------------------------------------

        $this->_add("default");

        //---------------------------------------
        // BACK-END RESOURCES
        //---------------------------------------

        $this->_add("cms")
             ->_add("cms:articles", "cms")
             ->_add("cms:auth", "cms")
             ->_add("cms:bug-report", "cms")
             ->_add("cms:calendar", "cms")
             ->_add("cms:categories", "cms")
             ->_add("cms:comments", "cms")
             ->_add("cms:error", "cms")
             ->_add("cms:galleries", "cms")
             ->_add("cms:pages", "cms")
             ->_add("cms:photos", "cms")
             ->_add("cms:tags", "cms")
             ->_add("cms:users", "cms");

        //---------------------------------------
        // GUEST PERMISSIONS
        //---------------------------------------

        $this->allow("guest", "default")
             ->allow("guest", "cms:auth")           // -- guests can attempt to log-in
             ->allow("guest", "cms:error")          // -- guests can break stuff
             ->allow("guest", "cms:bug-report");    // -- guests can report bugs

        //---------------------------------------
        // ADMIN PERMISSIONS
        //---------------------------------------

        $this->allow("admin")
             ->deny("admin", null, "purge")                       // -- admins cannot purge (normally)
             ->deny("admin", "cms:comments", "create");           // -- only devs can create a comment

        //---------------------------------------
        // DEVELOPER PERMISSIONS
        //---------------------------------------

        $this->allow("developer");             // -- unrestricted access

        return $this;
    }

    /**
     * Adds a Resource having an identifier unique to the ACL.
     *
     * @param Zend_Acl_Resource_Interface $resource       The resource to add
     * @param Zend_Acl_Resource_Interface|string $parent  A parent resource it inherits from
     * @return Typeoneerror_Acl                           Reference to Acl class
     */
    protected function _add($resource, $parent = null)
    {
        $this->add(new Zend_Acl_Resource($resource), $parent);

        return $this;
    }

    /**
     * Wrapper for <code>addRole</code>
     *
     * @param Zend_Acl_Resource_Interface $resource        The resource to add
     * @param Zend_Acl_Resource_Interface|string $parents  Parent resources it inherits from
     * @return Typeoneerror_Acl                            Reference to Acl class
     */
    protected function _addRole($role, $parents = null)
    {
        $this->addRole(new Zend_Acl_Role($role, $parents));

        return $this;
    }

}

編集

Typeoneerror_Controller_Plugin_Aclまた、リソースが要求されるたびに使用されるを持っていることも説明する必要があると思います。ここでは、要求されたリソースが作成する「タグ」を作成し、ユーザーがそのタグにアクセスできるかどうかを確認します。

    $controller = $request->controller;
    $action = $request->action;
    $module = (empty($request->module)) ? "default" : $request->module;

    // -- this ends up like "cms:articles" just like my resources
    $resource = $module . ":" . $controller;

    if (!$this->__acl->has($resource))
    {
        $resource = $module;
    }

    // -- the good stuff. check if the user's role can access the resource and action
    if (!$this->__acl->isAllowed($role, $resource, $action))
    {
        //more code 
    }
于 2010-02-17T00:08:10.877 に答える