私は Yii を使用してサイトを構築しようとしていますが、Yii のアクセス制御メタファーについて明確にする必要がある状況に陥っています。具体的には、の子孫でaccessRulesメソッドをオーバーライドできます。CController
前提条件:
これは Gii によってデフォルトで生成されたコードで、ドキュメンテーションによく似ています:
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'roles'=> array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
質問:
ここではっきりしないのは、現在の 1 人のユーザーとアクションのみの権限をチェックするのではなく、なぜ多くの異なるユーザーとグループ、および異なるアクションに対してアクセス ルールを定義する必要があるのかということです。-- ここでイタリック体で私の主な質問が強調表示されています。
このコードは、特定の 、特定の 、および特定の が既に知られている特定のリクエストのコンテキストで実行controller
さaction
れuser
ます。たとえば、ユーザーがゲストの場合、「管理者」ロールまたは認証済みユーザーのルールを定義する理由がわかりません。
理由:
いくつかの精緻化の後、私は次の実装にたどり着きました:
public function accessRules()
{
return array(
array(Yii::app()->user->hasRights()?'allow':'deny'),
);
}
子孫に追加された単純なカスタム メソッドは次のとおりですhasRights
。CWebUser
class WebUser extends CWebUser
{
private $ACL = // ACL example
array('user' => // controller id
array('index' => User::AC_MODERATOR, // action ids
'view' => User::AC_MODERATOR,
'create' => User::AC_MODERATOR,
'update' => User::AC_ADMIN,
'delete' => User::AC_ADMIN,
'admin' => User::AC_ADMIN),
// ...
);
public function hasRights()
{
return (Yii::app()->user->getState('accessRights') >=
$this->ACL[Yii::app()->controller->id][Yii::app()->controller->action->id]);
}
}
ご覧のとおり、hasRights
現在のユーザーの「権限」(通常どおり DB から読み取る)、現在のコントローラー、およびアクションを使用して、アクセスに関する決定として単一のブール値true
またはfalse
値を計算します。
このアプローチの何が問題なのですか? Yii がデフォルトでそのような単純なものを使用しないのはなぜですか?
Gii によって生成されたaccessRules
上記は過剰に見えるだけでなく、アクセス ルールが多くのコントローラーに分散していることを暗示しています。私のアプローチでは、単一のコンパクトな ACL が使用されます。