2.3. 高度な使用法

2.3.1. ACL データの保存による永続性の確保

Zend_Acl は、特定のバックエンド技術 (たとえばデータベースやキャッシュサーバを使用した ACL データの保存など) に依存しないように作られています。 すべて PHP のみで実装されているので、Zend_Acl 用の管理ツールを独自に作成して 管理の手間を省くことも可能になっています。 ACL の管理を対話的に行いたいという場面も数多く発生するでしょう。そのため Zend_Acl では、アプリケーションのアクセス制御を設定したり、 それに対して問い合わせたりするメソッドを用意しています。

データの使用法にはさまざまなものが考えられるので、 ACL データの保存は、場面に応じて開発者側で考えることになります。 Zend_Acl はシリアライズ可能なので、ACL オブジェクトを PHP の serialize() 関数でシリアライズすることができます。シリアライズした結果を、 ファイルやデータベースあるいはキャッシュなどのお好みの場所に保存することができます。

2.3.2. アサーションを使用した条件付き ACL 規則の作成

あるリソースに対する特定のロールのアクセス権限が、 固定ではなく条件に応じて変化することもあります。 たとえば、アクセスを認めるのは午前 8 時から午後 5 時の間に限定するといった場合です。 別の例としては、ブラックリストに載っている特定の IP アドレスからのアクセスのみを拒否するといったことがあります。 Zend_Acl は、必要に応じた任意の条件にもとづく規則を組み込みでサポートしています。

Zend_Acl は、条件付きの規則を Zend_Acl_Assert_Interface でサポートしています。規則のアサーション用インターフェイスを使用するには、 これを実装したクラスで assert() メソッドを作成します。

<?php
require_once 'Zend/Acl/Assert/Interface.php';

class CleanIPAssertion implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null,
                           Zend_Acl_Resource_Interface $resource = null, $privilege = null)
    {
        return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
    }

    protected function _isCleanIP($ip)
    {
        // ...
    }
}

アサーションクラスを作成したら、条件付きの規則を定義を割り当てる際に このアサーションクラスのインスタンスを指定します。 アサーションつきで作成された規則は、アサーションメソッドが true を返す場合にのみ適用されます。

<?php
require_once 'Zend/Acl.php';

$acl = new Zend_Acl();
$acl->allow(null, null, null, new CleanIPAssertion());

上のコードが作成する条件付き規則は、 誰からのアクセスであってもすべての権限を許可しますが、リクエスト元の IP アドレスが "ブラックリストに載っている" 場合にのみアクセスを拒否するというものです。 リクエスト元の IP が "クリーン" ではないとみなされた場合は、 アクセス許可規則が適用されません。この規則はすべてのロールおよびリソースの すべての権限に対して適用されるので、"クリーンではない" IP からのアクセスは拒否することになります。 しかし、これは特殊なケースです。通常は (つまり特定のロールやリソース、 権限を規則の対象とする場合)、アサーションに失敗して規則が適用されなかった場合には、 別の規則を使用してアクセスの可否を判断させるべきです。

アサーションオブジェクトの assert() メソッドは、認証問い合わせ (すなわち isAllowed()) が適用される ACL、ロール、リソース および権限に渡されます。これを用いて、必要な場所でアサーションクラスが 条件を判断します。