1

役割、タスク、および操作の階層を設定し、ユーザーに割り当てて、操作をミラーリングする controller:action を使用します。

docsから、ユーザーが操作にアクセスできることを確認したい場合は、次のように確認します。

if(Yii::app()->user->checkAccess('createPost'))

これは、ユーザーが対応するロールに対して承認されているかどうかを確認するために、すべてのアクションにコードを手動で追加する必要があるという印象を与えます。私は何かが欠けていますか - 確かに、アクションごとにこれを自動的に行う方法があります。

基本の Controller クラスを拡張し、Yii::app()->controller と Yii::app()->controller->action を使用してロールを生成し、ユーザーをチェックする何かを (preFilter に?) 追加することができます。その役割を許可されています。

しかし、これを行う方法がすでにあるに違いないと確信していますか?

accessRules フィルターでロールを渡すことができることは知っていますが、それはロール>タスク>操作階層を持つ目的を無効にしているようで、各アクションにそのようなルールを割り当てる必要があるのは、各関数でチェックを行うのと同じくらい悪いです最初の場所。

/item/delete などを実行しているユーザーが操作 'item:delete' (または DB AuthItem テーブルで期待される形式) に対して承認されていることを自動的にチェックする、他に欠けているオプションはありますか?

編集
データベースRBACと一緒にaccessRulesに関する問題を明確にします:

データベースに役割構造を定義します。それぞれが複数のタスクに対して承認された多数の役割であり、それらの役割は詳細な操作で構成されます (たとえば、役割「読者」はタスク「投稿の閲覧」に対して承認される場合があります。 'post/index' と 'post/view' のアップ)。次に、ユーザーを役割に割り当てます。これにより、その役割のタスクと、それらのタスク内の操作に対する権限がユーザーに付与されます。次に、コントローラー アクション (つまり操作) に対してuser->checkAccessを呼び出すと 、その操作を含むタスクを含むロールに対してユーザーが承認されていることを DB でチェックします。

しかし、各コントローラーを調べて、各アクションに対してどのロールが承認されるかを定義すると、データベースで既に行った作業が重複し、ルールが競合する可能性があります。

4

3 に答える 3

2

フィルターがそのトリックを行ったようです。

protected/components/Controller.php で定義された基本コントローラーがあると仮定して、次の関数をそれに追加してフィルターを定義します。何らかの理由でコントローラーの基本クラスがない場合は、コントローラーのドキュメントで説明されているように、別のクラスでフィルターを定義します。とにかくそのようにする方が良い(より再利用可能)かもしれません。

public function filterAccessControl($filterChain)
{
    $controller = Yii::app()->controller->id;
    $action = Yii::app()->controller->action->id;

//The RBAC admin module I'm using creates entries for operations as, e.g. Post:Create
// You may need to change this to match whatever entry format you have in your AuthItem table
    $operation = ucfirst($controller) . ':' . ucfirst($action);
    Yii::log('Checking auth for user: ' . Yii::app()->user->id. ' to operation: ' . $operation, 'info');

    if(Yii::app()->user->checkAccess($operation))
    {
        Yii::log('User authorised', 'info');
        $filterChain->run();
        return true;
    }
    else
    {
        Yii::log('Unauthorised user!!!!!', 'info');
        throw new CHttpException(401, 'You are not authorized to perform this action.');            
        return false;
    }   
}

( RBAMを使用して、操作名を ControllerName:ActionName として格納する DB の Auth テーブルを管理しているため、ucfirst です)。

すべてのコントローラーのすべてのアクションに対してこのフィルターを実行するには、filters()関数を Controller.php に追加してフィルターを適用します。

public function filters()
{
    return array(
   'accessControl',
);
}

いくつかの注意事項:

  • コントローラーのいずれかに既存のフィルターがある場合は、代わりにこのフィルターを適用する必要があります。そのコントローラーのfilters()関数がこれをオーバーライドするためです。
  • 何らかの理由でいくつかの例外が必要な場合は、必要に応じてフィルターが適用されるアクションを制限できるため、とにかく各コントローラーで個別に実行する方が安全かもしれません。さらに、ここでのみ実行し、忘れて後で他のフィルターをコントローラーに追加すると、それらのアクセス制御が失われます!
  • これを行う前に、 authManager設定でデフォルトのゲスト ロールが設定されていること、およびそのロールが /site/login にアクセスできることを確認してください。そうしないとログインできません!(これが発生した場合は、整理するまでフィルターを無効にしてください)
于 2013-11-15T08:33:28.517 に答える
0

私の答えは、問題に新しい光を当てはめないかもしれません:

最終的に、アプリケーションは各操作を実行できるユーザーを推測できなくなります。誰がどのアクションを実行できるかを Yii に伝える必要があります - この方法 (長いかもしれません) または他の方法 (短いかもしれません)。

これは、各アクション メソッドの先頭に「checkAccess()」を追加し、ユーザーがアクセス権を持っていない場合はカスタム メッセージで反応する「長い道のり」で行うことができます。この方法は、たとえ長くても冗長でクリーンであるため、コードのメンテナンスが容易になることに注意してください。

ご指摘のとおり、「 accessRules」メソッドで「アクセス制御フィルター」を利用することもできます。それはより短いですが、部外者(コードのその精神的な領域から数か月離れた後、あなたである可能性があります)にはあまり明確ではないため、コードの保守性は低くなります。

RBAC で「アクセス制御フィルター」を使用しても、非常に優れたアクセス許可の階層と矛盾したり、損なわれたりしないことを指摘したいと思います。この階層は、相互に継承する役割で構成され、各役割はタスクと場合によっては操作で構成されていることを思い出してください (YMMV。私は通常、相互に継承する役割を行い、各役割はタスクで「構成」されており、そのうちのいくつかにはビズルールがあります)。 . さらに詳しく説明できれば、なぜこれが「役割>タスク>操作階層を持つという目的を無効にする」と思いますか?これは、この議論にとって実り多いものです。

于 2013-11-15T06:54:48.247 に答える