<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 16855 -->
<sect1 id="zend.auth.adapter.http">

    <title>HTTP 認証アダプタ</title>

    <sect2 id="zend.auth.adapter.http.introduction">

        <title>導入</title>

        <para>
            <classname>Zend_Auth_Adapter_Http</classname> は、
            <ulink url="http://tools.ietf.org/html/rfc2617">RFC-2617</ulink> や
            <ulink url="http://en.wikipedia.org/wiki/Basic_authentication_scheme">ベーシック</ulink>、
            <ulink url="http://en.wikipedia.org/wiki/Digest_access_authentication">ダイジェスト</ulink>
            <acronym>HTTP</acronym> 認証にほぼ準拠した実装を提供します。ダイジェスト認証とは
            <acronym>HTTP</acronym> 認証方式のひとつで、パスワードを平文でネットワークに送信する必要がないという点で
            ベーシック認証より優れています。
        </para>

        <para>
            <emphasis>主な機能</emphasis>
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    ベーシック認証およびダイジェスト認証の両方のサポート
                </para>
            </listitem>
            <listitem>
                <para>
                    サポートしているすべてのスキームを試みるので
                    クライアントは、サポートする任意のスキームで応答可能
                </para>
            </listitem>
            <listitem>
                <para>
                    プロキシ認証のサポート
                </para>
            </listitem>
            <listitem>
                <para>
                    テキストファイルを用いた認証のサポート、
                    あるいはデータベースなどのその他のソースによる認証用インターフェイスの提供
                </para>
            </listitem>
        </itemizedlist>

        <para>
            <acronym>RFC</acronym>-2617 の機能のうち、以下についてはまだ実装されていません。
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    nonce 値を追いかけることによる "stale" のサポート、
                    および再試行攻撃への防御
                </para>
            </listitem>
            <listitem>
                <para>
                    整合性チェックを含む認証 "auth-int"
                </para>
            </listitem>
            <listitem>
                <para>
                    Authentication-Info <acronym>HTTP</acronym> ヘッダ
                </para>
            </listitem>
        </itemizedlist>

    </sect2>

    <sect2 id="zend.auth.adapter.design_overview">

        <title>設計の概要</title>

        <para>
            このアダプタはふたつのサブコンポーネントで構成されています。
            ひとつは <acronym>HTTP</acronym> 認証クラス自身、そしてもうひとつはいわゆる "リゾルバ" です。
            <acronym>HTTP</acronym> 認証クラスは、ベーシック認証およびダイジェスト認証を扱うロジックをカプセル化します。
            このクラスは、リゾルバを使用してなんらかの保存データ (デフォルトはテキストファイル)
            からクライアントの ID を探します。認証データが "解決"
            されると、クライアントから送信された値に基づいて認証が成功したかどうかを判断します。
        </para>

    </sect2>

    <sect2 id="zend.auth.adapter.configuration_options">

        <title>設定オプション</title>

        <para>
            <classname>Zend_Auth_Adapter_Http</classname> クラスのコンストラクタには、
            設定配列を渡す必要があります。使用可能なオプションはいくつかあり、
            その中には必須のものもあります。
        </para>

        <table id="zend.auth.adapter.configuration_options.table">
            <title>設定オプション</title>
            <tgroup cols="3">
                <thead>
                    <row>
                        <entry>オプション名</entry>
                        <entry>必須かどうか</entry>
                        <entry>説明</entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry><emphasis><property>accept_schemes</property></emphasis></entry>
                        <entry>Yes</entry>
                        <entry>
                            そのアダプタがクライアントからどの認証スキームを受け取るのかを設定します。
                            <emphasis>'basic'</emphasis> や <emphasis>'digest'</emphasis>
                            を含む空白区切りの文字列でなければなりません。
                        </entry>
                    </row>
                    <row>
                        <entry><emphasis><property>realm</property></emphasis></entry>
                        <entry>Yes</entry>
                        <entry>
                            認証レルムを設定します。ユーザ名は、指定したレルム内で一意でなければなりません。
                        </entry>
                    </row>
                    <row>
                        <entry><emphasis><property>digest_domains</property></emphasis></entry>
                        <entry>
                            <property>'accept_schemes'</property> が <emphasis>'digest'</emphasis> を含む場合は Yes
                        </entry>
                        <entry>
                            空白区切りの <acronym>URI</acronym> のリストで、
                            同じ認証情報が有効となる場所を指定します。
                            <acronym>URI</acronym> は同一サーバ上でなくてもかまいません。
                        </entry>
                    </row>
                    <row>
                        <entry><emphasis><property>nonce_timeout</property></emphasis></entry>
                        <entry>
                            <property>'accept_schemes'</property> が <emphasis>'digest'</emphasis> を含む場合は Yes
                        </entry>
                        <entry>
                            nonce の有効期限を秒数で指定します。以下の注意を参照ください。
                        </entry>
                    </row>
                    <row>
                        <entry><emphasis><property>proxy_auth</property></emphasis></entry>
                        <entry>No</entry>
                        <entry>
                            デフォルトでは無効です。有効にすると、
                            元のサーバの認証のかわりにプロキシで認証を行います。
                        </entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <note>
            <para>
                現在の <property>nonce_timeout</property> の実装には、いくつかの副作用があります。
                この設定は、指定した nonce の有効期限、
                つまり事実上はクライアントの認証情報の有効期限を指定するためのものです。
                現在は、これを (たとえば) 3600 に設定すると、
                一時間ごとに新しい認証をクライアントに要求するようアダプタに設定します。
                これは将来のリリースで nonce の追跡と stale のサポートを実装した時点で解決する予定です。
            </para>
        </note>

    </sect2>

    <sect2 id="zend.auth.adapter.http.resolvers">

        <title>リゾルバ</title>

        <para>
            リゾルバの仕事は、ユーザ名とレルムを受け取って何らかの証明を返すことです。
            ベーシック認証では、ユーザのパスワードを Base64 でエンコードしたものを受け取ります。
            ダイジェスト認証では、ユーザ名、レルムおよびパスワード
            (をコロンでつなげたもの) のハッシュを受け取ります。
            現在サポートしているハッシュアルゴリズムは <acronym>MD5</acronym> のみです。
        </para>

        <para>
            <classname>Zend_Auth_Adapter_Http</classname>
            <classname>Zend_Auth_Adapter_Http_Resolver_Interface</classname>
            を実装したオブジェクトを使用しています。
            このアダプタにはテキストファイル用のリゾルバクラスが含まれていますが、
            リゾルバインターフェイスを実装することで、
            その他のリゾルバも簡単に作成できます。
        </para>

        <sect3 id="zend.auth.adapter.http.resolvers.file">

            <title>File リゾルバ</title>

            <para>
                ファイルリゾルバは、非常にシンプルなクラスです。
                ファイル名を指定するプロパティを保持しており、
                コンストラクタでこれを指定することができます。
                <methodname>resolve()</methodname> メソッドはテキストファイルを走査し、
                ユーザ名とレルムにマッチする行を探します。テキストファイルのフォーマットは
                Apache の htpasswd ファイルと似た形式で
            </para>

            <programlisting language="txt"><![CDATA[
<username>:<realm>:<credentials>\n
]]></programlisting>

            <para>
                のようになります。個々の行は
                ユーザ名、レルムおよび認証情報の三つのフィールドで構成されており、
                それらがコロンで区切られています。リゾルバは認証情報フィールドの内容を理解することはできません。
                取得した値をそのまま呼び出し元に返します。したがって、
                同じ形式でベーシック認証およびダイジェスト認証の両方に対応できます。
                ベーシック認証では、このフィールドは平文テキストで書く必要があります。
                ダイジェスト認証では、これは先ほど説明したような <acronym>MD5</acronym> ハッシュとなります。
            </para>

            <para>
                ファイルリゾルバを作成する方法は次の二通りで、どちらも同じくらい簡単です。まずは
            </para>

            <programlisting language="php"><![CDATA[
$path     = 'files/passwd.txt';
$resolver = new Zend_Auth_Adapter_Http_Resolver_File($path);
]]></programlisting>

            <para>
                もうひとつは
            </para>

            <programlisting language="php"><![CDATA[
$path     = 'files/passwd.txt';
$resolver = new Zend_Auth_Adapter_Http_Resolver_File();
$resolver->setFile($path);
]]></programlisting>

            <para>
                指定したパスが空だったり読み込みできなかったりした場合は、
                例外をスローします。
            </para>

        </sect3>

    </sect2>

    <sect2 id="zend.auth.adapter.http.basic_usage">

        <title>基本的な使用法</title>

        <para>
            まず、必須設定項目を含む配列を作成します。
        </para>

        <programlisting language="php"><![CDATA[
$config = array(
    'accept_schemes' => 'basic digest',
    'realm'          => 'My Web Site',
    'digest_domains' => '/members_only /my_account',
    'nonce_timeout'  => 3600,
);
]]></programlisting>

        <para>
            この配列は、アダプタに対してベーシック認証およびダイジェスト認証の両方を受け付けるように指定します。
            また、<filename>/members_only</filename> および <filename>/my_account</filename>
            の配下では認証済みアクセスが必要となるようにします。
            realm の値は、通常はブラウザのパスワードダイアログボックスに表示されます。
            <property>nonce_timeout</property> は、もちろん、先ほど説明したとおりの振る舞いをします。
        </para>

        <para>
            次に、<classname>Zend_Auth_Adapter_Http</classname> オブジェクトを作成します。
        </para>

        <programlisting language="php"><![CDATA[
require_once 'Zend/Auth/Adapter/Http.php';
$adapter = new Zend_Auth_Adapter_Http($config);
]]></programlisting>

        <para>
            ベーシック認証およびダイジェスト認証の両方をサポートしているので、
            ふたつのリゾルバオブジェクトを作成する必要があります。
            これは、単にふたつの異なるクラスを作成するだけの簡単なことです。
        </para>

        <programlisting language="php"><![CDATA[
$basicResolver = new Zend_Auth_Adapter_Http_Resolver_File();
$basicResolver->setFile('files/basicPasswd.txt');

$digestResolver = new Zend_Auth_Adapter_Http_Resolver_File();
$digestResolver->setFile('files/digestPasswd.txt');

$adapter->setBasicResolver($basicResolver);
$adapter->setDigestResolver($digestResolver);
]]></programlisting>

        <para>
            最後に、認証を行います。このアダプタは、
            リクエストオブジェクトおよびレスポンスオブジェクトの両方を参照する必要があります。
        </para>

        <programlisting language="php"><![CDATA[
assert($request instanceof Zend_Controller_Request_Http);
assert($response instanceof Zend_Controller_Response_Http);

$adapter->setRequest($request);
$adapter->setResponse($response);

$result = $adapter->authenticate();
if (!$result->isValid()) {
    // ユーザ名/パスワードが間違っている、あるいはパスワード入力をキャンセルした
}
]]></programlisting>

    </sect2>

</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
