-1

私は、楽しくて教育的な目的のために、厳密にカスタム フレームワークに取り組んでいます。アクセス許可の実装方法に関するこの質問を読みましたが、答えが気に入っています。デコレータ パターンを使用するか、ディスパッチャーからの URL に基づいてパーミッションをチェックします。

私の質問は、アクセス許可のホワイト リストをどのように生成する必要があるかということです。コントローラー内のすべてのメソッドに実行許可を要求したくないので、たとえば、メソッド名の前に「x」を付けるなどの特別な命名規則を使用できます。

class CalendarController
{
    public function index($year = null, $month = null, $day = null)
    {
        // display calendar (no permission needed)
    }

    public function xAddEvent()
    {
        // display form to add event (permission required)
    }

    public function xAddEventSubmit()
    {
        // submit form to add event (permission required)
    }
}

次に、すべてのコントローラーを反復処理して x-method を返すスクリプトを作成し、さまざまなロールに割り当てるアクセス許可のリストを取得できます。

別のオプションとして、各コントローラーのプロパティとしてアクセス許可をハードコードすることもできます。次に例を示します。

class CalendarController
{
    public $permissions = array('addEvent',
                                'addEventSubmit');

    public function index($year = null, $month = null, $day = null)
    {
        // display calendar (no permission needed)
    }


    public function addEvent()
    {
        // display form to add event (permission required)
    }

    public function addEventSubmit()
    {
        // submit form to add event (permission required)
    }
}

より良い代替手段はありますか、それとも正しい軌道に乗っていますか?

4

3 に答える 3

1

注:これは主に、リンクされた記事で提供したソリューションの拡張になります。hakreからの回答についてはコメントしません。

あなたの質問を理解しているように、問題は基本的に、各メソッドに個別にアクセス権を設定したくないということです。

オプション 1: 飾らない

Decoratorを含むソリューションの利点の 1 つは、セキュリティで保護されたクラス (たとえば、Controllerアプリケーションの任意の部分である可能性があります) を使用するときに、それが装飾されていることを知る必要がないことです。したがって、誰でも完全にアクセスできるコントローラーがある場合は、それらを装飾することはできません。

このアプローチでは、コントローラのインスタンス化を担当するファクトリが、デコレータでラップする必要がある、またはラップしてはならないコントローラのリストを必要とする可能性が最も高くなります。これには常にifリストを参照するステートメントが必要になるため、個人的には、複数のメソッドを呼び出すインスタンスに対してのみこれを検討します (私の場合、コントローラーは除外されます)。

オプション 2: ワイルドカードとホワイトリスト

これに取り組む別の方法は、実際に承認を確認する方法を利用することです。

$command = [ get_class($this->target), $method ];

これは、照合されるトークンでした。これは、ACL がメソッドの名前だけでなく、完全なクラス名 (名前空間を含む) も受け取ることを意味します。クラスとメソッドの両方の名前を含むルールのリストを作成する機会が与えられます。次のようなもの:

Controllers\Identification::*  anonymous
Controllers\*::*               admin
Controllers\Users::view        authenticated
Controllers\Users::remove      manager
Controllers\Users::add         manager

アイデアは、許可されたすべての対話を定義する構成を保存することです。ACL はリストをたどり、ユーザーのグループをチェックし、最初の一致で結果を返します (この例では、管理者は認証されていないユーザーにのみ許可されているログイン ページを除くすべてにアクセスできます)。繰り返しますが、この特定の例は、少なくとも部分的な groups-contain-groups 機能を実装することに依存します。

また、これにはホワイトリストのみを使用する必要があることを繰り返します。マネージャーがユーザーを削除できるようにするのを忘れても、重大なリスクは追加されませんが、ユーザーが他のユーザーを削除することを拒否するのを忘れると、ブラックリスト ベースの承認を使用するときに重大なミスになる可能性があります。

私の2セント

于 2013-05-04T21:00:34.783 に答える
1

メソッドのオーバーロードについて考えたことはありますか? これは非常に簡単な例です。基本的に、関数が見つからない場合は、その__call()関数を使用してキャッチします。次に、アクセス許可のチェックを行い、正しいプライベート メソッドまたは保護されたメソッドを呼び出すことができます。

class CalendarController
{
    public function index($year = null, $month = null, $day = null)
    {
        // display calendar (no permission needed)
    }

    public function __call($name, $arguments)
    {
        // do your permission checks here
        if ($name == 'addEvent' && $this->hasPermission()) {
            return $this->_addEvent($arguments);
        }

        return false;
    }

    protected function _addEvent($params) {

    }
}
于 2013-05-02T20:41:52.727 に答える
0

他のフレームワークを調べて、制限を実装する方法を理解することをお勧めします。たとえば、yii は、要求された特定のアクションと、ユーザーが特定のレベルのパーミッションを持っているかどうかに基づいて、アクセス制限を実装します。RBAC を強くお勧めします ( http://en.wikipedia.org/wiki/Role-based_access_control )

Yii の例:

public function accessRules()
{
    return array(
        array('allow',  // allow all users to perform 'list' and 'show' actions
            'actions'=>array('list','show'),
            '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'),
            'users'=>array('admin'),
        ),
        array('deny',  // deny all users
            'users'=>array('*'),
        ),
    );
}

また、特定のタイプの HTTP リクエストで特定のアクションをリクエストする必要があることを示すフィルターも実装しています。次の例は、作成アクションを実行するには、HTTP 要求が POST でなければならないことを示しています。

public function filters()
{
    return array(
        'accessControl', // perform access control for CRUD operations
        'postOnly + create', // we only allow create via POST request
    );
}

リソース: http://www.larryullman.com/2010/01/14/yii-framework-access-control-lists/

参照: http://www.yiiframework.com/wiki/169/configuring-controller-access-rules-to-default-deny/

于 2013-05-02T20:31:06.190 に答える