ACLコンポーネントによるアクセス制御
更新日 2022-02-19 20:30:48
cakephp3
Aclプラグインのインストールと設定
Aclプラグインのインストール
composer require cakephp/acl:dev-master
config/bootstrap.phpに以下を記述する
\App\Application::addPlugin('Acl',['bootstrap' => true]);
Acl用のテーブルを作成
// aros、acos、aros_acosの3テーブルを作成
bin/cake migrations migrate -p Acl
各ファイルの設定
AppController.php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
use Cake\Controller\ComponentRegistry;
use Acl\Controller\Component\AclComponent;
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Acl.Acl');
$this->loadComponent('Auth', [
'loginAction' => [
'prefix' => false,
'controller' => 'Users',
'action' => 'login',
],
'loginRedirect' => [
'prefix' => false,
'controller' => 'Pages',
'action' => 'display',
'home',
],
'logoutRedirect' => [
'prefix' => false,
'controller' => 'Users',
'action' => 'login',
],
// 認証の種類
'authenticate' => [
'Ldap',
'Form' => [
'fields' => [
'username' => 'username',
'password' => 'password',
]
]
],
// 権限チェックの方法
'authorize' => [
// Acl認証 => isAuthorizedメソッド不要
'Acl.Actions' => ['actionPath' => 'controllers/'],
// カスタム認証 => isAuthorizedメソッドを使う場合
'Controller',
],
]);
}
// ※有効にするには'authorize' => ['Controller'] に設定する
public function isAuthorized($user)
{
$Collection = new ComponentRegistry();
$acl = new AclComponent($Collection);
$controller = $this->request->controller;
$action = $this->request->action;
return $acl->check(['Users' => ['id' => $user['id']]], "$controller/$action");
}
}
GroupsTable.php
class GroupsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('groups');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->addBehavior('Acl.Acl', ['type' => 'requester']); // 追加
$this->hasMany('Users', [
'foreignKey' => 'group_id',
]);
}
}
UsersTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('users');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->addBehavior('Acl.Acl', ['type' => 'requester']); // 追加
$this->belongsTo('Groups', [
'foreignKey' => 'group_id',
'joinType' => 'INNER',
]);
}
Group.php
class Group extends Entity
{
public function parentNode()
{
return null;
}
}
User.php
class User extends Entity
{
public function parentNode()
{
if (!$this->id) {
return null;
}
if (isset($this->group_id)) {
$group_id = $this->group_id;
} else {
$users_table = TableRegistry::getTableLocator()->get('Users');
$user = $users_table->find('all', ['fields' => ['group_id']])->where(['id' => $this->id])->first();
$group_id = $user->group_id;
}
if (!$group_id) {
return null;
}
return ['Groups' => ['id' => $group_id]];
}
}
権限設定
Aros作成Group追加、User追加をおこなうことによりarosが作成される
acos作成
// コマンドを実行して一括作成
bin/cake acl_extras aco_sync
// (新しくControllerやActionを追加した場合は下記のコマンドで更新する)
bin/cake acl_extras aco_update
パーミッションの設定例
bin/cake acl grant Groups.1 controllers
bin/cake acl deny Groups.2 controllers
bin/cake acl grant Groups.2 controllers/Posts
bin/cake acl grant Groups.2 controllers/Widgets
bin/cake acl deny Groups.3 controllers
bin/cake acl grant Groups.3 controllers/Posts/index
bin/cake acl grant Groups.3 controllers/Posts/view
bin/cake acl grant Groups.3 controllers/Widgets/index
bin/cake acl grant Groups.3 controllers/Widgets/view
任意に権限チェックをする方法
AppControllerのisAuthorizedを呼ぶ
// コントローラーのアクション内
$user = $this->request->getSession()->read('Auth.User');
$flag = $this->isAuthorized($user);
※Helperにメソッドを作成してもOK。ちなみに$userは配列でもエンティティでも大丈夫みたい。