私は現在、Yiiフレームワークの下でWebサイトを開発しようとしていますが、プログラムにはロールベースのアクセス制御(RBAC)が必要です。ガイドからRBACにフィルターを使用できることを読みましたが、管理者とユーザーが2つのテーブルに格納されている場合はどうすればよいでしょうか。つまり、データベースに管理者用とユーザー用の2つのテーブルがある場合、アクセス制御をどのように実装する必要がありますか?ありがとうございました。
3 に答える
それは可能です。ただし、トリッキーであり、これが将来問題を引き起こさないことを保証することはできません。必要なのはAuthAssignment
、たとえばAuthAssignment_Admins
とのような2つ以上のテーブルを用意し、それが呼び出されるたびに(たとえば、ロールを割り当てるときやアクセス許可を確認するとき)、関連するテーブルAuthAssignment_Customers
を参照していることを確認することです。CDbAuthManager
遠くから始めますが、その理由は理解できます。
ログインしたユーザーがどのテーブル/カテゴリに属しているかを通知するメカニズムを作成する必要があります。これは、を拡張することで実行できます
Yii::app()->user
。ここで説明します。特別なパラメータ(例)を追加するか、authTable
割り当てられたモデルと比較する必要があります。を拡張する必要があります
CDbAuthManager
。CDbAuthManagerTwoTables
たとえばコンポーネントでクラスを作成し、 inでconfig.php
inをauthManager
として参照します'class' => 'CDbAuthManagerTwoTables'
。のCDbAuthManagerTwoTables
<?php class CDbAuthManagerTwoTables extends CDbAuthManager { // public $assignmentTable = 'AuthAssignment'; public $assignmentTable = 'AuthAssignment_Customers'; // you may want to have AuthAssignment_Customers to be your default table function __construct() { if (!Yii::app()->user->isGuest) { if (Yii::app()->user->authTable == 'admin') { $this->assignmentTable = 'AuthAssignment_Admins'; } else { $this->assignmentTable = 'AuthAssignment_Customers'; } } } public function setType($assignmentTable = '') { // this method will be needed during authentication switch ($assignmentTable) { case 'Admin': $assignmentTable = 'AuthAssignment_Admins'; break; case 'Customer': $assignmentTable = 'AuthAssignment_Customers'; break; default: $assignmentTable = 'AuthAssignment_Customers'; break; } $this->assignmentTable = $assignmentTable; } }
認証時に割り当てます。すでにログインフォームが分離されており、にメソッドが分離されていることを前提としています
UserIdentity.php
。コードのどこかで次のようにします。$this->setState('authTable', 'admin'); $auth = Yii::app()->authManager; // You should already have this in your code $auth->setType('Admin'); // call to our new method from CDbAuthManagerTwoTables if (!$auth->isAssigned($user->role, $this->_id)) { if ($auth->assign($user->role, $this->_id)) { Yii::app()->authManager->save(); } }
ステップ4はありません。
したがって、同じことがCustomers
他のテーブルや承認にも当てはまります。あなたのために働いた場合の方法を教えてください。
これは箱から出しては不可能だと思います。authassignmentのdbスキーマを確認すると、usersテーブルに関連するuseridフィールドがあることがわかります。2つの異なるテーブルがある場合は、認証テーブルに別の一意の識別子が必要になります。ユーザー用に2つの異なるテーブルを用意することが絶対に必要ですか?実際、RBACは関心の分離に非常に役立ちます。つまり、1つのユーザーテーブルがありますが、「admin」、「editor」などの異なるロールをユーザーに割り当てることができます。2つの異なるユーザーテーブルがある場合、ユーザーが管理者になった場合はどうしますか?これは、処理する必要のない複雑さです。どうしても必要な場合は、RBAC機能を拡張して、異なるテーブルを参照できるようにする必要があります。
UserIDの保存方法を変更する
私は現在この正確な問題に取り組んでおり、私の解決策は、ユーザーIDが割り当てテーブルに格納される方法を変更することでした。整数のuserIDだけを格納する代わりに、IDとユーザーのタイプを示す文字列を格納します。
auth_assignments.userid["<typeId>.<userId>"] VARCHAR(64) NOT NULL
ロールを割り当てたりチェックしたりするときは、通常のIDの代わりにユーザーの「認証ID」が使用されます。このアプローチに関するフィードバックをお待ちしています。