7

私は PHP アプリケーションに取り組んでおり、いくつかのオブジェクトにアクセス制御を追加したいと考えています。この質問は言語固有のものではないと感じているため、この質問に PHP のタグを付けませんでした。

「サービスクラス」があるとします

abstract class Service {


}

多くのサービスがこれを基本クラスとして使用します。疑似例の 1 つを次に示します。

class Companies extends Service {

  function getCompanyInfo($id) {
      //...
  }

}

後で、アクセス制御を追加したいと思います。サンプルの「getCompanyInfoById」メソッドは「読み取り」操作であるため、これには「読み取り」権限が必要です。

この時点で、次の方法でこれを実装できます。

  1. アクセス制御を Service クラスに追加します。すべてのメソッド (getCompanyInfoById など) は、操作を完了して結果を返す前に、「hasPrivilege」メソッドを内部的に呼び出す必要があります。
  2. 内部オブジェクトでメソッドを呼び出す前に権限をチェックするある種の Proxy オブジェクトですべての Service オブジェクトをラップします。
  3. アクセス制御を完全に分離し、「呼び出し元」にメソッドを呼び出す前に権限を確認させます。

すべてのオプションの短所:

  1. これには、すべてのサービスを変更する必要があり、アクセス制御を認識する必要があります。これは関心の分離に反すると思います。
  2. これにより、ポリモーフィズムなどの OOP 機能が壊れます。呼び出し元は、サービスがサポートするインターフェイスを認識しなくなります。
  3. これは最も柔軟ですが、パーミッションのチェックが暗黙的に行われるという大きな欠点があります。開発者が「忘れる」か、複雑なコードパスにより、許可されていないサービスが呼び出される可能性があります。

これに完全にアプローチするより良い方法はありますか?

4

3 に答える 3

3

Java EEモデルはほぼ2行目です。コードは「コンテナ」で実行され、インターフェイスエントリポイント(サーブレットのURL、EJBのメソッド)についてコンテナに通知し、これらのエントリポイントを使用できるロールを定義します。 。管理者は認証情報(LDAPユーザーやグループなど)を特定の役割にマップし、コンテナーはそのマッピングを参照してエントリポイントへのアクセスを許可します。

ここで重要なのは、コンテナがコードを「認識」していることです。これは事実上、非常に巧妙なプロキシです。

コンテナがない場合は、おそらく何らかのアスペクト指向技術を使用して、プロキシアプローチを検討します。

オプション3は非常に脆弱であり、クライアントプログラマーの責任が大きすぎるというのは正しいと思います。

于 2009-12-17T11:24:58.373 に答える
3

別の解決策は、あなたの1の少し変種かもしれません.

元。

class Service
{
  var $ACL = //some hash map with acl
}

class Companies extends Service
{

  function getCompanyById($id)
  {
    //real code
  }
}

class SafeCompanies extends Companies
{
//If a method must be "protected" with an ACL, you must override them in this way
  function getCompanyById($id)
  {
    $this->check('read'); //raise an exception if current user haven't READ privilege
    parent::getCompanyById($id);    
  }  
} 

このようにして、責任を混在させず、ポリモーフィズムを使用できます

私の2セント

于 2009-12-17T15:19:58.837 に答える