あいどる💖たいむ

あいどるやってます。

Phalcon ACLによるアクセスコントロール

ACLでアクセスコントロールを行うメモ

環境

Phalcon 3.2.2

実装

InvoチュートリアルのACLのコードを元に自分のサービス用に改変している。

Tutorials : Invo - Phalcon Framework

デフォルト設定

setDefaultActionメソッドで、デフォルトはすべてのアクセスを禁止する。

use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Resource;
use Phalcon\Acl\Adapter\Memory as AclList;

$acl = new AclList();

$acl->setDefaultAction(Acl::DENY);

ロール

以下の3つのロールを作成する。

ロール 備考
Guest ゲスト用ロール
User ユーザ用ロール
Admin 管理者用ロール、Userを継承
// ロールの作成
$userRole = new Role('Users');
$adminRole = new Role('Admin');
$guestRole = new Role('Guest');
$roles = [$userRole, $adminRole, $guestRole];

// aclにロールを登録
$acl->addRole($userRole);
$acl->addRole($guestRole);
$acl->addRole($adminRole, $userRole); // 第2引数に指定したロールを継承できる。

リソース

Invoのチュートリアルでは、一つ一つのアクション名をリストに追加していたが、コントローラ別で設定したい場合もあると思う。 そのようなときのために、$ALL_ACTIONS定数を用意した。

// リソースのすべてのアクセスを許可するための文字列
static $ALL_ACTIONS = '_all_actions';

$resources = [
    'index' => [$ALL_ACTIONS],
    'items' => [$ALL_ACTIONS],
    'accounts' => ['index', 'login', 'signUp', 'manage'],
];

foreach ($resources as $resource => $actions) {
    $acl->addResource(new Resource($resource), $actions);
}

アクセス権の設定

次のようなアクセス権を設定する。

リソース 各ロールに対する設定内容
index すべてのロールで、すべてのアクセスを許可
items すべてのロールで、すべてのアクセスを許可
accounts Adminロールはすべてのアクセス許可、Usersは"manage"以外を許可、Guestはすべて禁止
// 全ロールに許可するリソースはまとめて許可
$publicResources = ['items', 'index'];
foreach ($roles as $role) {
    foreach ($publicResources as $resource) {
        foreach ($resources[$resource] as $action) {
            $acl->allow($role->getName(), $resource, $action);
        }
    }
}

// ロール別の許可設定
$acl->allow('Users', 'accounts', ['index', 'login', 'signUp']);
// Adminにmanageを追加(AdminはUsersを継承しているので、すでに1行上でUsersに許可しているindexなどの設定は不要)
$acl->allow('Admin', 'accounts', ['manage']);

動作確認

isAllowedメソッドを呼び出し、確認する。

var_dump($acl->isAllowed('Guest', 'index', $ALL_ACTIONS)); // true
var_dump($acl->isAllowed('Guest', 'accounts', 'index')); // false

var_dump($acl->isAllowed('Users', 'accounts', 'index')); // true
var_dump($acl->isAllowed('Users', 'accounts', 'manage')); // false

// AdminロールはUsersロールを継承しているので’accounts/index'のアクセスも可能
var_dump($acl->isAllowed('Admin', 'accounts', 'index')); // true
var_dump($acl->isAllowed('Admin', 'accounts', 'manage')); // true

実際のアプリケーションでの使用はInvoのように、{リソース名=コントローラ名、アクセス名=アクション名}のアクセス権があるか確認するようにして使うが、$ALL_ACTIONSが許可されているかもORで調べる。

$role = 'Users';
$controller = 'items';
$action = 'index';

$isAllowed =
    $acl->isAllowed($role, $controller, $action)
    || $acl->isAllowed($role, $controller, $ALL_ACTIONS);
var_dump($isAllowed);

全体ソース

phalcon_acl_example.php · GitHub

参考