TigerZF
🌐Español

15.4. Adaptador de autenticación HTTP

15.4.1. Introducción

Zend_Auth_Adapter_Http ofrece una implementación mayormente conforme con RFC-2617, de autenticación HTTP Basic y Digest. La autenticación Digest es un método de autenticación HTTP que mejora la autenticación Basic al proporcionar una forma de autenticarse sin tener que transmitir la contraseña en texto claro a través de la red.

Características principales:

  • Soporta autenticación tanto Basic como Digest.

  • Emite retos (challenges) en todos los esquemas soportados, de modo que el cliente puede responder con cualquier esquema que soporte.

  • Soporta autenticación de proxy.

  • Incluye soporte para autenticarse contra archivos de texto y proporciona una interfaz para autenticarse contra otras fuentes, como bases de datos.

Hay algunas características notables de RFC-2617 que aún no están implementadas:

  • Seguimiento de nonces, que permitiría el soporte de "stale" y una mayor protección contra ataques de repetición (replay).

  • Autenticación con comprobación de integridad, o "auth-int".

  • La cabecera HTTP Authentication-Info.

15.4.2. Resumen del diseño

Este adaptador consta de dos subcomponentes: la propia clase de autenticación HTTP, y los llamados "Resolvers" (resolutores). La clase de autenticación HTTP encapsula la lógica para llevar a cabo tanto la autenticación Basic como la Digest. Utiliza un resolutor para buscar la identidad de un cliente en algún almacén de datos (un archivo de texto por defecto) y recuperar las credenciales de dicho almacén. Las credenciales "resueltas" se comparan entonces con los valores enviados por el cliente para determinar si la autenticación tiene éxito.

15.4.3. Opciones de configuración

La clase Zend_Auth_Adapter_Http requiere que se le pase un array de configuración a su constructor. Existen varias opciones de configuración disponibles, y algunas son obligatorias:

Tabla 15.1. Opciones de configuración

Nombre de la opción Obligatorio Descripción
accept_schemes Determina qué esquemas de autenticación aceptará el adaptador del cliente. Debe ser una lista separada por espacios que contenga 'basic' y/o 'digest'.
realm Establece el ámbito (realm) de autenticación; los nombres de usuario deben ser únicos dentro de un ámbito dado.
digest_domains Sí, cuando accept_schemes contiene digest Lista separada por espacios de URIs para las que la misma información de autenticación es válida. Las URIs no tienen que apuntar todas al mismo servidor.
nonce_timeout Sí, cuando accept_schemes contiene digest Establece el número de segundos durante los cuales el nonce es válido. Vea las notas a continuación.
proxy_auth No Desactivado por defecto. Actívelo para realizar autenticación de proxy, en lugar de la autenticación normal contra el servidor de origen.

[Note] Nota

La implementación actual de nonce_timeout tiene algunos efectos secundarios interesantes. Se supone que este parámetro determina el tiempo de vida válido de un nonce dado, o efectivamente cuánto tiempo se acepta la información de autenticación de un cliente. Actualmente, si se establece en 3600 (por ejemplo), hará que el adaptador solicite nuevas credenciales al cliente cada hora, en punto. Esto se resolverá en una futura versión, una vez que se implementen el seguimiento de nonces y el soporte de "stale".

15.4.4. Resolutores (Resolvers)

El trabajo del resolutor es tomar un nombre de usuario y un ámbito (realm), y devolver algún tipo de valor de credencial. La autenticación Basic espera recibir la versión codificada en Base64 de la contraseña del usuario. La autenticación Digest espera recibir un hash del nombre de usuario, el ámbito y su contraseña (cada uno separado por dos puntos). Actualmente, el único algoritmo de hash soportado es MD5.

Zend_Auth_Adapter_Http depende de objetos que implementen Zend_Auth_Adapter_Http_Resolver_Interface. Con este adaptador se incluye una clase resolutora de archivo de texto, pero se puede crear cualquier otro tipo de resolutor simplemente implementando la interfaz del resolutor.

15.4.4.1. Resolutor de archivo

El resolutor de archivo es una clase muy simple. Tiene una única propiedad que especifica un nombre de archivo, el cual también puede pasarse al constructor. Su método resolve() recorre el archivo de texto, buscando una línea con un nombre de usuario y ámbito coincidentes. El formato del archivo de texto es similar al de los archivos htpasswd de Apache:

<username>:<realm>:<credentials>\n

Cada línea consta de tres campos: nombre de usuario, ámbito (realm) y credenciales, separados por dos puntos. El campo de credenciales es opaco para el resolutor de archivo; simplemente devuelve ese valor tal cual al que lo invoca. Por lo tanto, este mismo formato de archivo sirve tanto para la autenticación Basic como para la Digest. En la autenticación Basic, el campo de credenciales debe escribirse en texto claro. En la autenticación Digest, debe ser el hash MD5 descrito anteriormente.

Hay dos formas igualmente sencillas de crear un resolutor de archivo:

$path     = 'files/passwd.txt';
$resolver = new Zend_Auth_Adapter_Http_Resolver_File($path);

o bien

$path     = 'files/passwd.txt';
$resolver = new Zend_Auth_Adapter_Http_Resolver_File();
$resolver->setFile($path);

Si la ruta indicada está vacía o no se puede leer, se lanza una excepción.

15.4.5. Uso básico

Primero, configure un array con los valores de configuración requeridos:

$config = array(
    'accept_schemes' => 'basic digest',
    'realm'          => 'My Web Site',
    'digest_domains' => '/members_only /my_account',
    'nonce_timeout'  => 3600,
);

Este array hará que el adaptador acepte tanto autenticación Basic como Digest, y requerirá acceso autenticado a todas las áreas del sitio bajo /members_only y /my_account. El valor del ámbito (realm) suele mostrarlo el navegador en el cuadro de diálogo de contraseña. El nonce_timeout, por supuesto, se comporta como se ha descrito anteriormente.

A continuación, cree el objeto Zend_Auth_Adapter_Http:

$adapter = new Zend_Auth_Adapter_Http($config);

Dado que soportamos tanto la autenticación Basic como la Digest, necesitamos dos objetos resolutores diferentes. Tenga en cuenta que esto bien podría ser dos clases distintas:

$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);

Finalmente, realizamos la autenticación. El adaptador necesita una referencia tanto al objeto Request como al objeto Response para poder hacer su trabajo:

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()) {
    // Bad userame/password, or canceled password prompt
}