第3章 Zend_Auth

目次

3.1. 導入
3.1.1. アダプタ
3.1.2. 結果
3.1.3. ID の永続性
3.1.4. Zend_Auth の使用法
3.2. ダイジェスト認証
3.2.1. 導入
3.2.2. 使用
3.2.3. ID

3.1. 導入

Zend_Auth は、認証のための API を提供します。 また、一般的な使用例に対応する具象認証アダプタも用意しています。

[注意] 注意

Zend_Auth には、 ダイジェスト認証用のアダプタ だけが含まれています。これは、Zend_Auth の考え方を説明するためのシンプルな設計のアダプタです。 今後、さらにいろいろなアダプタを開発する予定です。 「こんなアダプタがほしい」っていう方はいますか? そんな皆さんは、ぜひ 投票に参加 してください。あるいは、 自分でつくってしまう のも大歓迎です!

Zend_Auth が扱うのはあくまでも 認証 (authentication) であり、承認 (authorization) ではありません。 認証 (authentication) とはつまり、あるエンティティが何者であるのかを示す (識別する) ことです。これを、なんらかの条件にもとづいて行います。 承認 (authorization) とは、あるエンティティが他のエンティティに対して アクセスしたり何らかの操作をしたりする権限があるかどうかを判定する処理です。 これは Zend_Auth の対象外となります。 Zend Framework における認証やアクセス制御の詳細については、 Zend_Acl を参照ください。

3.1.1. アダプタ

Zend_Auth アダプタの使用目的は、 LDAP や RDBMS あるいはファイル のような特定の型の認証サービスに対する認証を行うことです。 アダプタによってそのオプションや挙動は大きくことなるでしょうが、 いくつかの基本処理は、あらゆるアダプタで共通となります。 たとえば認証条件 (いわゆる ID) を受け取り、認証を行い、 何らかの結果を返すという処理は、すべての Zend_Auth アダプタで共通です。

各 Zend_Auth 認証アダプタは、Zend_Auth_Adapter_Interface を実装しています。このインターフェイスで定義されているメソッドが authenticate() で、アダプタクラスはこれを実装して認証を行います。 各アダプタクラスは、authenticate() をコールする前に準備を済ませておく必要があります。 つまり、アダプタ側で用意しなければならない機能としては 認証条件 (ユーザ名およびパスワードなど) の取得や アダプタ固有のオプションの設定 (データベースのテーブルを使用するアダプタならデータベースへの接続設定など) があるということです。

以下にあげるのは認証アダプタのサンプルで、 これはユーザ名とパスワードを受け取って認証を行います。 その他の詳細、例えば認証サービスへの実際の問い合わせなどは、 例を簡潔にするため省略しています。

<?php
require_once 'Zend/Auth/Adapter/Interface.php';

class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
    /**
     * 認証用のユーザ名とパスワードを設定します
     *
     * @return void
     */
    public function __construct($username, $password)
    {
        // ...
    }

    /**
     * 認証を試みます
     *
     * @throws Zend_Auth_Adapter_Exception が、認証処理をできなかった場合に発生します
     * @return Zend_Auth_Result
     */
    public function authenticate()
    {
        // ...
    }
}

docblock コメントで説明しているとおり、 authenticate()Zend_Auth_Result (あるいは Zend_Auth_Result の派生クラス) のインスタンスを返す必要があります。何らかの理由で認証の問い合わせができなかった場合は、 authenticate()Zend_Auth_Adapter_Exception から派生した例外をスローしなければなりません。

3.1.2. 結果

Zend_Auth アダプタは、authenticate() の結果として Zend_Auth_Result のインスタンスを返します。 これにより、認証を試みた結果を表します。アダプタのインスタンスを作成した際に Zend_Auth_Result オブジェクトが作成され、 以下の三つのメソッドで Zend_Auth アダプタの結果に対する共通の操作ができます。

  • isValid() - その結果が 認証の成功を表している場合にのみ true を返します。

  • getIdentity() - 認証を試みた ID 情報を返します。

  • getMessages() - 認証に失敗した場合に、 関連するメッセージの配列を返します。

3.1.3. ID の永続性

認証情報 (パスワードなど) を含む認証を要求するのは便利なものですが、 リクエストごとにいちいち認証情報を引き回すのではなく、 認証済みの ID を保持し続けることも重要です。

HTTP はステートレスなプロトコルです。しかし、 クッキーやセッションといった技術によって、 サーバサイドのウェブアプリケーションでも 複数リクエスト間でステート (状態) を保持し続けられるようになりました。 Zend_Auth は、デフォルトで Zend_Session を使用しており、 認証に成功した後の ID 情報を PHP のセッションで永続管理するようにしています。

認証に成功すると、Zend_Auth::authenticate() は 認証結果の ID を永続ストレージに保存します。デフォルトでは、 Zend_Auth が使用するストレージクラスは Zend_Session にもとづいたものとなります。 ストレージクラスを変更するには、 Zend_Auth::setStorage() でストレージオブジェクトを指定します。

自動的に永続ストレージに ID を保存するのはまずい場合もあるでしょう。 そんな場合は、Zend_Auth クラスを使用せずに アダプタクラスを直接利用します。

3.1.4. Zend_Auth の使用法

Zend_Auth の使用法には、次の二通りがあります。

  1. 間接的に Zend_Auth::authenticate() 経由で使用する

  2. 直接、アダプタの authenticate() メソッドを使用する

次の例は、Zend_Auth アダプタを間接的に Zend_Auth クラスから使用するものです。

<?php
// Zend_Auth のシングルトンインスタンスへの参照を取得します
require_once 'Zend/Auth.php';
$auth = Zend_Auth::getInstance();

// 認証アダプタを設定します
$authAdapter = new MyAuthAdapter($username, $password);

// 認証を試み、その結果を取得します
$result = $auth->authenticate($authAdapter);

if (!$result->isValid()) {
    // 認証に失敗したので、原因を表示します
    foreach ($result->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // 認証に成功しました。ID ($username) がセッションに保存されます
    // $result->getIdentity() === $auth->getIdentity()
    // $result->getIdentity() === $username
}

上の例においてリクエスト内で認証が行われると、 認証に成功した際にその ID を取得するのは簡単なことです。

<?php
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // ID があるのでそれを取得します
    $identity = $auth->getIdentity();
}

永続ストレージから認証 ID を削除するには、単純に clearIdentity() メソッドを使用します。 これは、アプリケーションの "ログアウト" 処理を実装するためのものです。

<?php
Zend_Auth::getInstance()->clearIdentity();

自動的に永続ストレージが用いられるのがまずい場合もあるでしょう。 そんな場合は、Zend_Auth クラスをバイパスして アダプタクラスを直接使用します。 アダプタクラスを直接使用するとは、アダプタオブジェクトの設定と準備を行い、 その authenticate() メソッドをコールするということです。 アダプタ固有の詳細情報については、各アダプタのドキュメントで説明します。 以下の例は、MyAuthAdapter を直接使用するものです。

<?php
// 認証アダプタを設定します
$authAdapter = new MyAuthAdapter($username, $password);

// 認証を試み、その結果を取得します
$result = $authAdapter->authenticate();

if (!$result->isValid()) {
    // 認証に失敗したので、原因を表示します
    foreach ($result->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // 認証に成功しました
    // $result->getIdentity() === $username
}