|
|
@@ -9,65 +9,70 @@
|
|
|
<title>Introduction</title>
|
|
|
|
|
|
<para>
|
|
|
- <classname>Zend_Auth_Adapter_Http</classname> provides a mostly-compliant implementation
|
|
|
- of <ulink url="http://tools.ietf.org/html/rfc2617">RFC-2617</ulink>, <ulink
|
|
|
- url="http://en.wikipedia.org/wiki/Basic_authentication_scheme">Basic</ulink> and
|
|
|
- <ulink url="http://en.wikipedia.org/wiki/Digest_access_authentication">Digest</ulink>
|
|
|
- HTTP Authentication. Digest authentication is a method of HTTP authentication that
|
|
|
- improves upon Basic authentication by providing a way to authenticate without having to
|
|
|
- transmit the password in clear text across the network.
|
|
|
+ <classname>Zend_Auth_Adapter_Http</classname> provides a mostly-compliant
|
|
|
+ implementation of <ulink url="http://tools.ietf.org/html/rfc2617">RFC-2617</ulink>,
|
|
|
+ <ulink url="http://en.wikipedia.org/wiki/Basic_authentication_scheme">Basic</ulink>
|
|
|
+ and <ulink
|
|
|
+ url="http://en.wikipedia.org/wiki/Digest_access_authentication">Digest</ulink>
|
|
|
+ <acronym>HTTP</acronym> Authentication. Digest authentication is a method of
|
|
|
+ <acronym>HTTP</acronym> authentication that improves upon Basic authentication by
|
|
|
+ providing a way to authenticate without having to transmit the password in clear text
|
|
|
+ across the network.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
<emphasis>Major Features:</emphasis>
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Supports both Basic and Digest authentication.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Issues challenges in all supported schemes, so client can respond with any
|
|
|
- scheme it supports.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Supports proxy authentication.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Includes support for authenticating against text files and provides an
|
|
|
- interface for authenticating against other sources, such as databases.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
</para>
|
|
|
|
|
|
+ <itemizedlist>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Supports both Basic and Digest authentication.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Issues challenges in all supported schemes, so client can respond with any
|
|
|
+ scheme it supports.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Supports proxy authentication.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Includes support for authenticating against text files and provides an
|
|
|
+ interface for authenticating against other sources, such as databases.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ </itemizedlist>
|
|
|
+
|
|
|
<para>
|
|
|
- There are a few notable features of RFC-2617 that are not implemented yet:
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Nonce tracking, which would allow for "stale" support, and increased replay
|
|
|
- attack protection.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Authentication with integrity checking, or "auth-int".
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <para>
|
|
|
- Authentication-Info HTTP header.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
+ There are a few notable features of <acronym>RFC</acronym>-2617 that are not
|
|
|
+ implemented yet:
|
|
|
</para>
|
|
|
|
|
|
+ <itemizedlist>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Nonce tracking, which would allow for "stale" support, and increased replay
|
|
|
+ attack protection.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Authentication with integrity checking, or "auth-int".
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <para>
|
|
|
+ Authentication-Info <acronym>HTTP</acronym> header.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ </itemizedlist>
|
|
|
+
|
|
|
</sect2>
|
|
|
|
|
|
<sect2 id="zend.auth.adapter.design_overview">
|
|
|
@@ -75,12 +80,13 @@
|
|
|
<title>Design Overview</title>
|
|
|
|
|
|
<para>
|
|
|
- This adapter consists of two sub-components, the HTTP authentication class itself, and
|
|
|
- the so-called "Resolvers." The HTTP authentication class encapsulates the logic for
|
|
|
- carrying out both Basic and Digest authentication. It uses a Resolver to look up a
|
|
|
- client's identity in some data store (text file by default), and retrieve the
|
|
|
- credentials from the data store. The "resolved" credentials are then compared to the
|
|
|
- values submitted by the client to determine whether authentication is successful.
|
|
|
+ This adapter consists of two sub-components, the <acronym>HTTP</acronym> authentication
|
|
|
+ class itself, and the so-called "Resolvers." The <acronym>HTTP</acronym> authentication
|
|
|
+ class encapsulates the logic for carrying out both Basic and Digest authentication. It
|
|
|
+ uses a Resolver to look up a client's identity in some data store (text file by
|
|
|
+ default), and retrieve the credentials from the data store. The "resolved" credentials
|
|
|
+ are then compared to the values submitted by the client to determine whether
|
|
|
+ authentication is successful.
|
|
|
</para>
|
|
|
|
|
|
</sect2>
|
|
|
@@ -93,78 +99,80 @@
|
|
|
The <classname>Zend_Auth_Adapter_Http</classname> class requires a configuration array
|
|
|
passed to its constructor. There are several configuration options available, and some
|
|
|
are required:
|
|
|
- <table id="zend.auth.adapter.configuration_options.table">
|
|
|
- <title>Configuration Options</title>
|
|
|
- <tgroup cols="3">
|
|
|
- <thead>
|
|
|
- <row>
|
|
|
- <entry>Option Name</entry>
|
|
|
- <entry>Required</entry>
|
|
|
- <entry>Description</entry>
|
|
|
- </row>
|
|
|
- </thead>
|
|
|
- <tbody>
|
|
|
- <row>
|
|
|
- <entry><emphasis>accept_schemes</emphasis></entry>
|
|
|
- <entry>Yes</entry>
|
|
|
- <entry>
|
|
|
- Determines which authentication schemes the adapter will accept from
|
|
|
- the client. Must be a space-separated list containing
|
|
|
- <emphasis>'basic'</emphasis> and/or <emphasis>'digest'</emphasis>.
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry><emphasis>realm</emphasis></entry>
|
|
|
- <entry>Yes</entry>
|
|
|
- <entry>
|
|
|
- Sets the authentication realm; usernames should be unique within a
|
|
|
- given realm.
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry><emphasis>digest_domains</emphasis></entry>
|
|
|
- <entry>
|
|
|
- Yes, when <emphasis>'accept_schemes'</emphasis> contains
|
|
|
- <emphasis>'digest'</emphasis>
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Space-separated list of URIs for which the same authentication
|
|
|
- information is valid. The URIs need not all point to the same
|
|
|
- server.
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry><emphasis>nonce_timeout</emphasis></entry>
|
|
|
- <entry>
|
|
|
- Yes, when <emphasis>'accept_schemes'</emphasis> contains
|
|
|
- <emphasis>'digest'</emphasis>
|
|
|
- </entry>
|
|
|
- <entry>
|
|
|
- Sets the number of seconds for which the nonce is valid. See notes
|
|
|
- below.
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- <row>
|
|
|
- <entry><emphasis>proxy_auth</emphasis></entry>
|
|
|
- <entry>No</entry>
|
|
|
- <entry>
|
|
|
- Disabled by default. Enable to perform Proxy authentication, instead
|
|
|
- of normal origin server authentication.
|
|
|
- </entry>
|
|
|
- </row>
|
|
|
- </tbody>
|
|
|
- </tgroup>
|
|
|
- </table>
|
|
|
</para>
|
|
|
|
|
|
+ <table id="zend.auth.adapter.configuration_options.table">
|
|
|
+ <title>Configuration Options</title>
|
|
|
+ <tgroup cols="3">
|
|
|
+ <thead>
|
|
|
+ <row>
|
|
|
+ <entry>Option Name</entry>
|
|
|
+ <entry>Required</entry>
|
|
|
+ <entry>Description</entry>
|
|
|
+ </row>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <row>
|
|
|
+ <entry><emphasis>accept_schemes</emphasis></entry>
|
|
|
+ <entry>Yes</entry>
|
|
|
+ <entry>
|
|
|
+ Determines which authentication schemes the adapter will accept from
|
|
|
+ the client. Must be a space-separated list containing
|
|
|
+ <emphasis>'basic'</emphasis> and/or <emphasis>'digest'</emphasis>.
|
|
|
+ </entry>
|
|
|
+ </row>
|
|
|
+ <row>
|
|
|
+ <entry><emphasis>realm</emphasis></entry>
|
|
|
+ <entry>Yes</entry>
|
|
|
+ <entry>
|
|
|
+ Sets the authentication realm; usernames should be unique within a
|
|
|
+ given realm.
|
|
|
+ </entry>
|
|
|
+ </row>
|
|
|
+ <row>
|
|
|
+ <entry><emphasis>digest_domains</emphasis></entry>
|
|
|
+ <entry>
|
|
|
+ Yes, when <emphasis>'accept_schemes'</emphasis> contains
|
|
|
+ <emphasis>'digest'</emphasis>
|
|
|
+ </entry>
|
|
|
+ <entry>
|
|
|
+ Space-separated list of URIs for which the same authentication
|
|
|
+ information is valid. The URIs need not all point to the same
|
|
|
+ server.
|
|
|
+ </entry>
|
|
|
+ </row>
|
|
|
+ <row>
|
|
|
+ <entry><emphasis>nonce_timeout</emphasis></entry>
|
|
|
+ <entry>
|
|
|
+ Yes, when <emphasis>'accept_schemes'</emphasis> contains
|
|
|
+ <emphasis>'digest'</emphasis>
|
|
|
+ </entry>
|
|
|
+ <entry>
|
|
|
+ Sets the number of seconds for which the nonce is valid. See notes
|
|
|
+ below.
|
|
|
+ </entry>
|
|
|
+ </row>
|
|
|
+ <row>
|
|
|
+ <entry><emphasis>proxy_auth</emphasis></entry>
|
|
|
+ <entry>No</entry>
|
|
|
+ <entry>
|
|
|
+ Disabled by default. Enable to perform Proxy authentication, instead
|
|
|
+ of normal origin server authentication.
|
|
|
+ </entry>
|
|
|
+ </row>
|
|
|
+ </tbody>
|
|
|
+ </tgroup>
|
|
|
+ </table>
|
|
|
+
|
|
|
<note>
|
|
|
<para>
|
|
|
The current implementation of the <emphasis>nonce_timeout</emphasis> has some
|
|
|
interesting side effects. This setting is supposed to determine the valid lifetime
|
|
|
of a given nonce, or effectively how long a client's authentication information is
|
|
|
- accepted. Currently, if it's set to 3600 (for example), it will cause the adapter to
|
|
|
- prompt the client for new credentials every hour, on the hour. This will be resolved
|
|
|
- in a future release, once nonce tracking and stale support are implemented.
|
|
|
+ accepted. Currently, if it's set to 3600 (for example), it will cause the adapter
|
|
|
+ to prompt the client for new credentials every hour, on the hour. This will be
|
|
|
+ resolved in a future release, once nonce tracking and stale support are
|
|
|
+ implemented.
|
|
|
</para>
|
|
|
</note>
|
|
|
|
|
|
@@ -175,16 +183,18 @@
|
|
|
<title>Resolvers</title>
|
|
|
|
|
|
<para>
|
|
|
- The resolver's job is to take a username and realm, and return some kind of credential value. Basic
|
|
|
- authentication expects to receive the Base64 encoded version of the user's password. Digest authentication
|
|
|
- expects to receive a hash of the user's username, the realm, and their password (each separated by colons).
|
|
|
- Currently, the only supported hash algorithm is MD5.
|
|
|
+ The resolver's job is to take a username and realm, and return some kind of credential
|
|
|
+ value. Basic authentication expects to receive the Base64 encoded version of the user's
|
|
|
+ password. Digest authentication expects to receive a hash of the user's username, the
|
|
|
+ realm, and their password (each separated by colons). Currently, the only supported
|
|
|
+ hash algorithm is <acronym>MD5</acronym>.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
<classname>Zend_Auth_Adapter_Http</classname> relies on objects implementing
|
|
|
- <classname>Zend_Auth_Adapter_Http_Resolver_Interface</classname>. A text file resolver class is included with this
|
|
|
- adapter, but any other kind of resolver can be created simply by implementing the resolver interface.
|
|
|
+ <classname>Zend_Auth_Adapter_Http_Resolver_Interface</classname>. A text file resolver
|
|
|
+ class is included with this adapter, but any other kind of resolver can be created
|
|
|
+ simply by implementing the resolver interface.
|
|
|
</para>
|
|
|
|
|
|
<sect3 id="zend.auth.adapter.http.resolvers.file">
|
|
|
@@ -192,31 +202,46 @@
|
|
|
<title>File Resolver</title>
|
|
|
|
|
|
<para>
|
|
|
- The file resolver is a very simple class. It has a single property specifying a filename, which can also
|
|
|
- be passed to the constructor. Its <methodname>resolve()</methodname> method walks through the text file, searching
|
|
|
- for a line with a matching username and realm. The text file format similar to Apache htpasswd files:
|
|
|
- <programlisting language="txt"><![CDATA[
|
|
|
+ The file resolver is a very simple class. It has a single property specifying a
|
|
|
+ filename, which can also be passed to the constructor. Its
|
|
|
+ <methodname>resolve()</methodname> method walks through the text file, searching
|
|
|
+ for a line with a matching username and realm. The text file format similar to
|
|
|
+ Apache htpasswd files:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="txt"><![CDATA[
|
|
|
<username>:<realm>:<credentials>\n
|
|
|
]]></programlisting>
|
|
|
- Each line consists of three fields - username, realm, and credentials - each separated by a colon. The
|
|
|
- credentials field is opaque to the file resolver; it simply returns that value as-is to the caller.
|
|
|
- Therefore, this same file format serves both Basic and Digest authentication. In Basic authentication,
|
|
|
- the credentials field should be written in clear text. In Digest authentication, it
|
|
|
- should be the MD5 hash described above.
|
|
|
+
|
|
|
+ <para>
|
|
|
+ Each line consists of three fields - username, realm, and credentials - each
|
|
|
+ separated by a colon. The credentials field is opaque to the file resolver; it
|
|
|
+ simply returns that value as-is to the caller. Therefore, this same file format
|
|
|
+ serves both Basic and Digest authentication. In Basic authentication, the
|
|
|
+ credentials field should be written in clear text. In Digest authentication, it
|
|
|
+ should be the <acronym>MD5</acronym> hash described above.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
There are two equally easy ways to create a File resolver:
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$path = 'files/passwd.txt';
|
|
|
$resolver = new Zend_Auth_Adapter_Http_Resolver_File($path);
|
|
|
]]></programlisting>
|
|
|
+
|
|
|
+ <para>
|
|
|
or
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$path = 'files/passwd.txt';
|
|
|
$resolver = new Zend_Auth_Adapter_Http_Resolver_File();
|
|
|
$resolver->setFile($path);
|
|
|
]]></programlisting>
|
|
|
+
|
|
|
+ <para>
|
|
|
If the given path is empty or not readable, an exception is thrown.
|
|
|
</para>
|
|
|
|
|
|
@@ -230,7 +255,9 @@ $resolver->setFile($path);
|
|
|
|
|
|
<para>
|
|
|
First, set up an array with the required configuration values:
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$config = array(
|
|
|
'accept_schemes' => 'basic digest',
|
|
|
'realm' => 'My Web Site',
|
|
|
@@ -238,23 +265,29 @@ $config = array(
|
|
|
'nonce_timeout' => 3600,
|
|
|
);
|
|
|
]]></programlisting>
|
|
|
- This array will cause the adapter to accept either Basic or Digest authentication, and will require
|
|
|
- authenticated access to all the areas of the site under <filename>/members_only</filename> and
|
|
|
- <filename>/my_account</filename>. The realm value is usually displayed by the browser in the password dialog box.
|
|
|
- The <emphasis>nonce_timeout</emphasis>, of course, behaves as described above.
|
|
|
+
|
|
|
+ <para>
|
|
|
+ This array will cause the adapter to accept either Basic or Digest authentication, and
|
|
|
+ will require authenticated access to all the areas of the site under
|
|
|
+ <filename>/members_only</filename> and <filename>/my_account</filename>. The realm
|
|
|
+ value is usually displayed by the browser in the password dialog box. The
|
|
|
+ <emphasis>nonce_timeout</emphasis>, of course, behaves as described above.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- Next, create the Zend_Auth_Adapter_Http object:
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ Next, create the <classname>Zend_Auth_Adapter_Http</classname> object:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$adapter = new Zend_Auth_Adapter_Http($config);
|
|
|
]]></programlisting>
|
|
|
- </para>
|
|
|
|
|
|
<para>
|
|
|
- Since we're supporting both Basic and Digest authentication, we need two different resolver objects. Note
|
|
|
- that this could just as easily be two different classes:
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ Since we're supporting both Basic and Digest authentication, we need two different
|
|
|
+ resolver objects. Note that this could just as easily be two different classes:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$basicResolver = new Zend_Auth_Adapter_Http_Resolver_File();
|
|
|
$basicResolver->setFile('files/basicPasswd.txt');
|
|
|
|
|
|
@@ -264,12 +297,13 @@ $digestResolver->setFile('files/digestPasswd.txt');
|
|
|
$adapter->setBasicResolver($basicResolver);
|
|
|
$adapter->setDigestResolver($digestResolver);
|
|
|
]]></programlisting>
|
|
|
- </para>
|
|
|
|
|
|
<para>
|
|
|
- Finally, we perform the authentication. The adapter needs a reference to both the Request and Response
|
|
|
- objects in order to do its job:
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ Finally, we perform the authentication. The adapter needs a reference to both the
|
|
|
+ Request and Response objects in order to do its job:
|
|
|
+ </para>
|
|
|
+
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
assert($request instanceof Zend_Controller_Request_Http);
|
|
|
assert($response instanceof Zend_Controller_Response_Http);
|
|
|
|
|
|
@@ -281,7 +315,6 @@ if (!$result->isValid()) {
|
|
|
// Bad userame/password, or canceled password prompt
|
|
|
}
|
|
|
]]></programlisting>
|
|
|
- </para>
|
|
|
|
|
|
</sect2>
|
|
|
|