<?xml version="1.0" encoding="UTF-8"?>
    <!-- EN-Revision: 24249 -->
    <!-- Reviewed: no -->
<sect1 id="zend.auth.introduction">
    <title>Introducción</title>
    <para>
        <classname>Zend_Auth</classname> provee una <acronym>API</acronym> para
        autenticación e incluye adaptadores concretos de autenticación para
        escenarios de casos de uso común. </para>
    <para>
        <classname>Zend_Auth</classname> es concerniente sólo con
            <emphasis>autenticación</emphasis> y no con
            <emphasis>autorización</emphasis> . Autenticación es vagamente
        definido como: determinar si una entidad realmente es lo que pretende
        ser (o sea, identificación), basandose en un grupo de credenciales.
        Autorización, el proceso de decidir si se permite a una entidad: acceso
        a, o el realizar operaciones en, otras entidades esta fuera del alcance
        de <classname>Zend_Auth</classname> . Para más información sobre
        autorización y control de acceso con Zend Framework, por favor vea <link
            linkend="zend.acl">Zend_Acl</link> . </para>
    <note>
        <para> La clase <classname>Zend_Auth</classname> implementa el patrón
            Singleton - sólo una instancia de la clase está disponible - a
            través de su método estático <methodname>getInstance()</methodname>
            . Esto significa que usar el operador <emphasis>new</emphasis> y la
            keyword <emphasis>clone</emphasis> no va a funcionar con la clase
                <classname>Zend_Auth</classname> : use
                <methodname>Zend_Auth::getInstance()</methodname> en su lugar.
        </para>
    </note>
    <sect2 id="zend.auth.introduction.adapters">

        <title>Adaptadores</title>

        <para> Un adaptador <classname>Zend_Auth</classname> es usado para
            autenticar en contra de un tipo particular de servicio de
            autenticación, como <acronym>LDAP</acronym> ,
                <acronym>RDBMS</acronym> , o almacenamiento basado en ficheros.
            Diferentes adaptadores pueden tener opciones y compotamientos muy
            diferentes, pero algunas cosas básicas son comunes entre los
            adaptadores de autenticación. Por ejemplo, aceptar credenciales de
            autenticación (incluyendo una identidad supuesta), realizar
            consultas ante el servicio de autenticación, y regresar resultados,
            son comunes para los adaptadores <classname>Zend_Auth</classname> . </para>

        <para> Cada clase adaptadora <classname>Zend_Auth</classname> implementa
                <classname>Zend_Auth_Adapter_Interface</classname> . Esta
            interface define un metodo, <methodname>authenticate()</methodname>
            , que la clase adaptadora debe implementar para realizar una
            peticion de autenticación. Cada clase adaptadora debe ser preparada
            antes de llamar a <methodname>authenticate()</methodname> . Esta
            preparación del adaptador incluye la creación de credenciales (p.ej.
            nombre de usuario y contraseña) y la definición de valores para
            opciones de configuración especificos del adaptador, como valores de
            coneccion a base de datos para un adaptador de tabla de base de
            datos. </para>

        <para>El siguente ejemplo es un adaptador de autenticación que requiere
            que un nombre de usuario y contraseña sean especificados para la
            autenticación. Otros detalles, como la forma de realizar peticiones
            al servicio de autenticación, han sido omitídos por brevedad: </para>

        <programlisting language="php"><![CDATA[
class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
    /**
     * Establece nombre de usuario y contraseña para autenticacón
     *
     * @return void
     */
    public function __construct($username, $password)
    {
        // ...
    }

    /**
     * Realiza un intento de autenticación
     *
     * @throws Zend_Auth_Adapter_Exception Si la autenticación no puede
     *                                     ser realizada
     * @return Zend_Auth_Result
     */
    public function authenticate()
    {
        // ...
    }
}
]]></programlisting>

        <para> Como se ha indicado en su docblock,
                <methodname>authenticate()</methodname> debe regresar una
            instancia de <classname>Zend_Auth_Result</classname> (o de una clase
            derivada de <classname>Zend_Auth_Result</classname> ). Si por alguna
            razón es imposible realizar una petición de autenticación,
                <methodname>authenticate()</methodname> debería arrojar una
            excepción que se derive de
                <classname>Zend_Auth_Adapter_Exception</classname> . </para>

    </sect2>

    <sect2 id="zend.auth.introduction.results">

        <title>Resultados</title>

        <para> Los adaptadores <classname>Zend_Auth</classname> regresan una
            instancia de <classname>Zend_Auth_Result</classname> con
                <methodname>authenticate()</methodname> para representar el
            resultado de un intento de autenticación. Los adaptadores llenan el
            objeto <classname>Zend_Auth_Result</classname> en cuanto se
            construye, así que los siguientes cuatro métodos proveen un grupo
            básico de operaciones "frente al usuario" que son comunes a los
            resultados de adaptadores Zend_Auth: </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>isValid()</methodname> - regresa true si y solo
                    si el resultado representa un intento de autenticación
                    exitoso </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getCode()</methodname> - regresa una constante
                    identificadora <classname>Zend_Auth_Result</classname> para
                    determinar el tipo de fallo en la autenticación o si ha sido
                    exitosa. Este puede ser usado en situaciones cuando el
                    desarrollador desea distinguir entre varios tipos de
                    resultados de autenticación. Esto permite a los
                    desarrolladores, por ejemplo, mantener estadísticas
                    detalladas de los resultados de autenticación. Otro uso de
                    esta característica es: proporcionar al usuario mensajes
                    específicos detallados por razones de usabilidad, aunque los
                    desarrolladores son exhortados a considerar el riesgo de
                    proporcionar tales detalles a los usuarios, en vez de un
                    mensaje general de fallo en la autenticación. Para más
                    información, vea las siguientes notas: </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getIdentity()</methodname> - regresa la
                    identidad del intento de autenticación </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getMessages()</methodname> - regresa un arreglo
                    de mensajes pertinentes a un fallido intento de
                    autenticación </para>
            </listitem>
        </itemizedlist>

        <para>El desarrollador podría desear ramificar basado en el tipo de
            resultado de la autenticación a fin de realizar operaciones mas
            específicas. Algunas operaciones que los desarrolladores podrían
            encontrar útiles son: bloquear cuentas despues de varios intentos
            fallidos de ingresar una contraseña, marcar una dirección IP despues
            de que ha intentado muchas identidades no existentes, y porporcionar
            al usuario mensajes especificos resultados de la autenticación. Los
            siguientes codigos de resultado están disponibles: </para>

        <programlisting language="php"><![CDATA[
Zend_Auth_Result::SUCCESS
Zend_Auth_Result::FAILURE
Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
Zend_Auth_Result::FAILURE_UNCATEGORIZED
]]></programlisting>

        <para>El siguiente ejemplo ilustra como un desarrollador podría
            ramificar basado en el código resultado: </para>
        <programlisting language="php"><![CDATA[
// debtri de AuthController / loginAction
$result = $this->_auth->authenticate($adapter);

switch ($result->getCode()) {

    case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
        /** realiza algo para identidad inexistente **/
        break;

    case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
        /** realiza algo para credencial invalida **/
        break;

    case Zend_Auth_Result::SUCCESS:
        /** realiza algo para autenticación exitosa **/
        break;

    default:
        /** realiza algo para otras fallas **/
        break;
}
]]></programlisting>

    </sect2>

    <sect2 id="zend.auth.introduction.persistence">

        <title>Persistencia de Identidad</title>

        <para>Autenticar una petición que incluye credenciales de autenticación
            es util por sí mismo, pero también es importante el soportar
            mantener la identidad autenticada sin tener que presentar las
            credenciales de autenticación con cada petición.</para>

        <para>
            <acronym>HTTP</acronym> es un protocolo sin estado, sin embargo, se
            han desarrollado técnicas como las cookies y sesiones a fin de
            facilitar mantener el estado a través de multiples peticiones en
            aplicaciones web del lado del servidor. </para>

        <sect3 id="zend.auth.introduction.persistence.default">

            <title>Persistencia por Defecto en la Sesión PHP</title>

            <para> Por defecto, <classname>Zend_Auth</classname> provee
                almacenamiento persistente de la identidad desde un intento de
                autenticación exitoso usando la sesión <acronym>PHP</acronym> .
                En un intento de autenticación exitoso,
                    <methodname>end_Auth::authenticate()</methodname> almacena
                la identidad del resultado de autenticación en almacenamiento
                persistente. A menos que se configure diferente,
                    <classname>Zend_Auth</classname> usa una clase de
                almacenamiento llamada
                    <classname>Zend_Auth_Storage_Session</classname> , la cual,
                a su vez usa <link linkend="zend.session">
                    <classname>Zend_Session</classname>
                </link> . Una clase diferente podría ser utilizada mediante
                proveer un objeto que implemente
                    <classname>Zend_Auth_Storage_Interface</classname> a
                    <methodname>Zend_Auth::setStorage()</methodname>
            </para>

            <note>
                <para> Si el automático almacenamiento persistente de la
                    identidad no es apropiado para un caso en particular,
                    entonces los desarrolladores podrían dejar de usar la clase
                        <classname>Zend_Auth</classname> al mismo tiempo,
                    utilizando en su lugar una clase adaptadora directamente.
                </para>
            </note>

            <example id="zend.auth.introduction.persistence.default.example">

                <title>Modifying the Session Namespace</title>

                <para>
                    <classname>Zend_Auth_Storage_Session</classname> usa un
                    espacionombre (namespace) de sesión 'Zend_Auth'. Este
                    espacio-nombre podría ser OVERRIDDEN al pasar un valor
                    diferente al contructor de
                        <classname>Zend_Auth_Storage_Session</classname> , y
                    este valor es pasado internamente al constructor de
                        <classname>Zend_Session_Namespace</classname> . Esto
                    debería ocurrir antes de que se intente la autenticación, ya
                    que <methodname>Zend_Auth::authenticate()</methodname>
                    realiza el almacenamiento automático de la identidad. </para>

                <programlisting language="php"><![CDATA[
// Almacena una referencia a la instancia Singleton de Zend_Auth
$auth = Zend_Auth::getInstance();

// Usa 'unEspacionombre' en lugar de 'Zend_Auth'
$auth->setStorage(new Zend_Auth_Storage_Session('unEspacionombre'));

/**
 * @todo Set up the auth adapter, $authAdapter
 */

// Autenticar, almacenando el resultado, y persistiendo la identidad en
// suceso
$result = $auth->authenticate($authAdapter);
]]></programlisting>

            </example>

        </sect3>

        <sect3 id="zend.auth.introduction.persistence.custom">

            <title>Implementando Almacenamiento Personalizado</title>

            <para> En ocaciones los desarrolladores podrían necesitar usar un
                diferente comportamiento de persistencia de identidad que el
                provisto por <classname>Zend_Auth_Storage_Session</classname> .
                Para esos casos los desarrolladores podrían simplemente
                implementar <classname>Zend_Auth_Storage_Interface</classname> y
                suplir una instancia de la clase a
                    <methodname>Zend_Auth::setStorage()</methodname> . </para>

            <example id="zend.auth.introduction.persistence.custom.example">

                <title>Usando una Clase de Almacenamiento Personalizada</title>

                <para> Para poder utilizar una clase de almacenamiento
                    persistente de identidad diferente a
                        <classname>Zend_Auth_Storage_Session</classname> , el
                    desarrollador implementa
                        <classname>Zend_Auth_Storage_Interface</classname> :
                </para>
                   <programlisting language="php"><![CDATA[
class MyStorage implements Zend_Auth_Storage_Interface
{
    /**
     * Regresa true si y solo si el almacenamiento esta vacio
     *
     * @arroja Zend_Auth_Storage_Exception Si es imposible
     *                                     determinar si el almacenamiento
     *                                     esta vacio
     * @regresa boleano
     */
    public function isEmpty()
    {
        /**
         * @por hacer implementación
         */
    }

    /**
     * Regresa el contenido del almacenamiento
     *
     * El comportamiento es indefinido cuando el almacenamiento esta vacio
     *
     * @arroja Zend_Auth_Storage_Exception Si leer contenido de
     *                                     almacenamiento es imposible
     * @regresa mixto
     */
    public function read()
    {
        /**
         * @por hacer implementación
         */
    }

    /**
     * Escribe $contents al almacenamiento
     *
     * @parametros mezclado $contents
     * @arroja Zend_Auth_Storage_Exception Si escribir $contents al
     *                                     almacenamiento es imposible
     * @regresa boleano
     */
    public function write($contents)
    {
        /**
         * @por hacer implementación
         */
    }

    /**
     * limpia contenidos del almacenamiento
     *
     * @arroja Zend_Auth_Storage_Exception Si limpiar contenidos del
     *                                     almacenamiento es imposible
     * @regresa void
     */
    public function clear()
    {
        /**
         * @por hacer implementación
         */
    }
}
]]></programlisting>

                <para> A fin de poder usar esta clase de almacenamiento
                    personalizada,
                        <methodname>Zend_Auth::setStorage()</methodname> es
                    invocada antes de intentar una petición de autenticación: </para>
                <programlisting language="php"><![CDATA[
// Instruye Zend_Auth para usar la clase de almacenamiento personalizada
Zend_Auth::getInstance()->setStorage(new MyStorage());

/**
 * @por hacer Configurar el adaptador de autenticación, $authAdapter
 */

// Autenticar, almacenando el resultado, y persistiendo la identidad
// si hay exito
$result = Zend_Auth::getInstance()->authenticate($authAdapter);
]]></programlisting>

            </example>

        </sect3>

    </sect2>

    <sect2 id="zend.auth.introduction.using">

        <title>Uso</title>

        <para> Hay dos formas provistas de usar adaptadores
                <classname>Zend_Auth</classname> : </para>
        <orderedlist>
            <listitem>
                <para> indirectamente, a través de
                        <methodname>Zend_Auth::authenticate()</methodname>
                </para>
            </listitem>
            <listitem>
                <para> directamente, a través del metodo
                        <methodname>authenticate()</methodname> del adaptador
                </para>
            </listitem>
        </orderedlist>

        <para> El siguiente ejemplo ilustra como usar el adaptador
                <classname>:Zend_Auth</classname> : indirectamente, a través del
            uso de la clase <classname>Zend_Auth</classname> :
        </para>
            <programlisting language="php"><![CDATA[
// Recibe una referencia a la instancia singleton de Zend_Auth
$auth = Zend_Auth::getInstance();

// Configura el adaptador de autenticación
$authAdapter = new MyAuthAdapter($username, $password);

// Intenta la autenticación, almacenando el resultado
$result = $auth->authenticate($authAdapter);

if (!$result->isValid()) {
    // Fautenticación fallida: imprime el por que
    foreach ($result->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // Autenticación exitosa, la identidad ($username) es almacenada
    // en la sesión
    // $result->getIdentity() === $auth->getIdentity()
    // $result->getIdentity() === $username
}
]]></programlisting>

        <para>Una vez que la autenticación ha sido intentada en una petición,
            como en el ejemplo anterior, es fácil verificar si existe una
            identidad autenticada exitosamente: </para>
        <programlisting language="php"><![CDATA[
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // Existe la identidad; obtenla
    $identity = $auth->getIdentity();
}
]]></programlisting>

        <para> Para remover una identidad del almacenamiento persistente,
            simplemente usa el metodo <methodname>clearIdentity()</methodname>
            method. Comunmente esto sería usado para implementar una operación
            "cerrar sesión" en la aplicación:
        </para>
            <programlisting language="php"><![CDATA[
Zend_Auth::getInstance()->clearIdentity();
]]></programlisting>

        <para> Cuando el uso automático de almacenamiento persistente es
            inapropiado para un caso en particular, el desarrollador podría
            simplemente omitir el uso de la clase
                <classname>Zend_Auth</classname> , usando una clase adaptadora
            directamente. El uso directo de una clase adaptadora implica
            configurar y preparar un objeto adaptador y despues llamar a su
            metodo <methodname>authenticate()</methodname> . Los detalles
            específicos del adaptador son discutidos en la documentación de cada
            adaptador. El siguiente ejemplo utiliza directamente
                <classname>MyAuthAdapter</classname> : </para>

        <programlisting language="php"><![CDATA[
// Configura el adaptador de autenticación
$authAdapter = new MyAuthAdapter($username, $password);

// Intenta la autenticación, almacenando el resultado
$result = $authAdapter->authenticate();

if (!$result->isValid()) {
    // Autenticación fallida, imprime el porque
    foreach ($result->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // Autenticación exitosa
    // $result->getIdentity() === $username
}
]]></programlisting>

    </sect2>

</sect1>
