<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.auth.introduction">
    <title>Introduction</title>

    <para>
        <classname>Zend_Auth</classname> fournit une <acronym>API</acronym> pour l'authentification
        et inclut des adaptateurs concrets d'authentification pour les cas les plus courants.
    </para>

    <para>
        <classname>Zend_Auth</classname> est uniquement concerné par
        <emphasis>le processus d'authentification</emphasis> et non pas par
        <emphasis>le processus d'autorisation</emphasis>. L'authentification est définie de
        manière lâche (souple) afin de déterminer si une entité donnée est bien celle qu'elle
        prétend être (c.-à-d. identification), sur la base d'identifiants fournis. L'autorisation,
        l'action de décider si une entité donnée peut accéder à d'autres entités et&#160;/&#160;ou
        exécuter des opérations sur celles-ci ne fait pas partie des prérogatives de
        <classname>Zend_Auth</classname>. Pour plus d'informations sur les autorisations et le
        contrôle d'accès via Zend Framework, voyez
        <link linkend="zend.acl"><classname>Zend_Acl</classname></link>.
    </para>

    <note>
        <para>
            La classe <classname>Zend_Auth</classname> inclut un singleton - uniquement une
            instance de la classe est disponible - à travers la méthode statique
            <methodname>getInstance()</methodname>. Celle ci utilise un opérateur
            <emphasis>new</emphasis> et le mot-clé <emphasis>clone</emphasis> ne fonctionnera pas
            avec la classe <classname>Zend_Auth</classname>, utilisez plutôt
            <methodname>getInstance()</methodname>.
        </para>
    </note>

    <sect2 id="zend.auth.introduction.adapters">
        <title>Adaptateurs</title>

        <para>
            Un adaptateur <classname>Zend_Auth</classname> est utilisé pour authentifier via
            un service particulier d'authentification, comme <acronym>LDAP</acronym>,
            <acronym>RDBMS</acronym> ou un stockage basé sur des fichiers. Les différents
            adaptateurs peuvent posséder des options et des comportements très divers. Cependant,
            quelques méthodes de base leur sont communes. Par exemple, accepter des éléments
            d'authentification (incluant une identité prétendue), authentifier et retourner un
            résultat sont des éléments communs aux adaptateurs <classname>Zend_Auth</classname>.
        </para>

        <para>
            Chaque classe d'adaptateur <classname>Zend_Auth</classname> implémente
            <classname>Zend_Auth_Adapter_Interface</classname>. Cette interface définit une
            méthode, <methodname>authenticate()</methodname>, celle-ci est implémentée par une
            classe adaptateur à fin de réaliser l'authentification. Chaque classe adaptateur doit
            être préparée avant tout appel de <methodname>authenticate()</methodname>. Cela implique
            que chaque adaptateur fournisse la possibilité de définir des éléments
            d'authentification (par exemple identifiant et mot de passe) et de définir des valeurs
            pour les options spécifiques de l'adaptateur, tels que les paramètres de connexion à une
            base de données pour un adaptateur qui en fait usage.
        </para>

        <para>
            L'exemple suivant est un adaptateur d'authentification qui requiert un
            identifiant et un mot de passe. D'autres détails, tel que la manière d'interroger le
            service d'authentification, ont été omis par souci de clarté&#160;:
        </para>

        <programlisting language="php"><![CDATA[
class MonAdaptateurAuth implements Zend_Auth_Adapter_Interface
{
    /**
     * Définition de l'identifiant et du mot de passe
     * pour authentification
     *
     * @return void
     */
    public function __construct($identifiant, $motdepasse)
    {
        // ...
    }

    /**
     * Réalise une tentative d'authentification
     *
     * @throws Zend_Auth_Adapter_Exception Si l'authentification
     *                                     ne peut pas être réalisée
     * @return Zend_Auth_Result
     */
    public function authenticate()
    {
        // ...
    }
}
]]></programlisting>

        <para>
            Comme indiqué dans la documentation "docblock", <methodname>authenticate()</methodname>
            doit retourner une instance de <classname>Zend_Auth_Result</classname> (ou d'une classe
            dérivée de <classname>Zend_Auth_Result</classname>). Si pour quelque raison que ce
            soit, la requête d'authentification ne peut pas être réalisée,
            <methodname>authenticate()</methodname> retournera une exception dérivée de
            <classname>Zend_Auth_Adapter_Exception</classname>.
        </para>
    </sect2>

    <sect2 id="zend.auth.introduction.results">
        <title>Résultats</title>

        <para>
            Les adaptateurs <classname>Zend_Auth</classname> retournent une instance de
            <classname>Zend_Auth_Result</classname> via <methodname>authenticate()</methodname> de
            manière à présenter les résultats d'une tentative d'authentification. Les adaptateurs
            alimentent l'objet <classname>Zend_Auth_Result</classname> lors de sa construction, de
            manière à ce que les quatre méthodes suivantes fournissent de base un lot d'opérations
            communes aux résultats des adaptateurs <classname>Zend_Auth</classname>&#160;:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>isValid()</methodname>&#160;: retourne <constant>TRUE</constant> si
                    et seulement si le résultat représente une tentative réussie d'authentification.
                </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getCode()</methodname>&#160;: retourne une constante
                    <classname>Zend_Auth_Result</classname> qui détermine le type de retour
                    accepté ou refusé (N.D.T. : voir tableau ci dessous). Cela peut être utilisé
                    pour les développeurs voulant distinguer en amont les différents types de
                    résultat. Il est possible d'avoir des statistiques détaillées, par exemple.
                    Une autre utilisation est la personnalisation du message de retour au
                    client. Attention cependant à ne pas trop donner de détails aux clients
                    pour des raisons de sécurité. Pour plus de détails, consultez les notes
                    ci-dessous.
                </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getIdentity()</methodname>&#160;: retourne l'identité de la
                    tentative d'authentification.
                </para>
            </listitem>
            <listitem>
                <para>
                    <methodname>getMessages()</methodname>&#160;: retourne un tableau de messages
                    relatifs à une tentative infructueuse d'authentification.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Un développeur peut connecter le résultat de l'authentification avec des
            opérations spécifiques. Certaines opérations développées peuvent bloquer le compte
            après plusieurs refus du mot de passe, bannir une adresse IP après plusieurs essais sur
            des comptes inexistants ou fournir un message spécifique à l'utilisateur final. Les
            codes suivants sont disponibles&#160;:
        </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>
            L'exemple suivant illustre comment utiliser le retour&#160;:
        </para>

        <programlisting language="php"><![CDATA[
// A l'intérieur de la méthode AuthController / loginAction
$resultat = $this->_auth->authenticate($adapter);

switch ($resultat->getCode()) {

    case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
        /** l'identifiant n'existe pas **/
        break;

    case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
        /** mauvaise authentification **/
        break;

    case Zend_Auth_Result::SUCCESS:
        /** authentification acceptée **/
        break;

    default:
        /** autres cas **/
        break;
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.auth.introduction.persistence">
        <title>Persistance d'identité</title>

        <para>
            Authentifier une requête qui contient des paramètres d'authentification est utile
            en soi, mais il est également important de permettre le maintien de l'identité
            authentifiée sans avoir à représenter ces paramètres d'authentification à chaque
            requête.
        </para>

        <para>
            <acronym>HTTP</acronym> est un protocole sans état, cependant, des techniques telles que
            les cookies ou les sessions ont été développées de manière à faciliter le maintien d'un
            contexte lors de multiples requêtes dans les applications Web.
        </para>

        <sect3 id="zend.auth.introduction.persistence.default">
            <title>Persistance par défaut dans une session PHP</title>

            <para>
                Par défaut, <classname>Zend_Auth</classname> fournit un stockage persistant de
                l'identité, après une authentification réussie, via les sessions
                <acronym>PHP</acronym>. Après une authentification réussie,
                <methodname>Zend_Auth::authenticate()</methodname> conserve
                l'identité résultant de l'authentification dans un stockage persistant. A moins
                d'une configuration particulière, <classname>Zend_Auth</classname> utilise une
                classe de stockage nommée <classname>Zend_Auth_Storage_Session</classname>, qui
                utilise <link linkend="zend.session"><classname>Zend_Session</classname></link>.
                Une classe personnalisée peut être utilisée pour fournir un objet implémentant
                <classname>Zend_Auth_Storage_Interface</classname> à
                <methodname>Zend_Auth::setStorage()</methodname>.
            </para>

            <note>
                <para>
                    Si la persistance automatique de l'identité n'est pas souhaitable dans un
                    cas particulier, alors le développeur peut renoncer à utiliser la classe
                    <classname>Zend_Auth</classname> et préférer utiliser directement une classe
                    adaptateur.
                </para>
            </note>

            <example id="zend.auth.introduction.persistence.default.example">
                <title>Changer l'espace de nommage de la session</title>

                <para>
                    <classname>Zend_Auth_Storage_Session</classname> utilise un espace de
                    nommage de <classname>Zend_Auth</classname>. Cet espace peut être écrit en
                    passant les valeurs au constructeur de
                    <classname>Zend_Auth_Storage_Session</classname>, et ces valeurs sont passées en
                    interne au constructeur de <classname>Zend_Session_Namespace</classname>. Cela
                    doit être fait avant l'authentification, et avant que
                    <methodname>Zend_Auth::authenticate()</methodname> ait accompli le stockage
                    automatique de l'identité.
                </para>

                <programlisting language="php"><![CDATA[
// Sauver une référence du singleton, instance de Zend_Auth
$auth = Zend_Auth::getInstance();

// Utiliser 'unEspaceDeNommage' instance de 'Zend_Auth'
$auth->setStorage(new Zend_Auth_Storage_Session('unEspaceDeNommage'));

/**
 * @todo Paramètrage de l'adaptateur d'authentification :
 *       $authAdaptateur
 */

// authentification, sauvegarde du résultat
// et stockage du résultat en cas de succès
$resultat = $auth->authenticate($authAdaptateur);
]]></programlisting>
            </example>
        </sect3>

        <sect3 id="zend.auth.introduction.persistence.custom">
            <title>Installer un stockage personnalisé</title>

            <para>
                Parfois les développeurs ont besoin d'utiliser un comportement de persistance
                d'identité différent de celui fourni par
                <classname>Zend_Auth_Storage_Session</classname>. Dans ces cas, les développeurs
                implémentent simplement <classname>Zend_Auth_Storage_Interface</classname> et
                fournissent t une instance de la classe à
                <methodname>Zend_Auth::setStorage()</methodname>.
            </para>

            <example id="zend.auth.introduction.persistence.custom.example">
                <title>Utiliser une classe de stockage personnalisée</title>

                <para>
                    Pour utiliser une classe de stockage d'identité persistante autre que
                    <classname>Zend_Auth_Storage_Session</classname>, le développeur commence par
                    implémenter <classname>Zend_Auth_Storage_Interface</classname>&#160;:
                </para>

                <programlisting language="php"><![CDATA[
class MonStockage implements Zend_Auth_Storage_Interface
{
    /**
     * Retourne true si et seulement si le stockage est vide
     *
     * @throws Zend_Auth_Storage_Exception S'il est impossible de déterminer
     *                                     si le stockage est vide
     * @return boolean
     */
    public function isEmpty()
    {
        /**
         * @todo implémentation
         */
    }

    /**
     * Retourne le contenu du stockage
     *
     * Comportement à définir si le stockage est vide.
     *
     * @throws Zend_Auth_Storage_Exception Si la lecture du stockage
     *                                     est impossible
     * @return mixed
     */
    public function read()
    {
        /**
         * @todo implémentation
         */
    }

    /**
     * Ecrit $contents dans le stockage
     *
     * @param  mixed $contents
     * @throws Zend_Auth_Storage_Exception Si l'écriture de $contents
     *                                     est impossible
     * @return void
     */
    public function write($contents)
    {
        /**
         * @todo implementation
         */
    }

    /**
     * RAZ du stockage
     *
     * @throws Zend_Auth_Storage_Exception Si la remise à zéro (RAZ)
     *                                     est impossible
     * @return void
     */
    public function clear()
    {
        /**
         * @todo implementation
         */
    }

}
]]></programlisting>

                <para>
                    Ensuite la classe personnalisée est invoquée, avant la requête
                    d'authentification, avec <methodname>Zend_Auth::setStorage()</methodname>&#160;:
                </para>

                <programlisting language="php"><![CDATA[
// Définit la classe personnalisée à utiliser
Zend_Auth::getInstance()->setStorage(new MonStockage());

/**
 * @todo Paramètrage de l'adaptateur d'authentification :
 *       $authAdaptateur
 */

// Authentification, sauvegarde et
// persistance du résultat en cas de succès.
$result = Zend_Auth::getInstance()->authenticate($authAdaptateur);
]]></programlisting>
            </example>
        </sect3>
    </sect2>

    <sect2 id="zend.auth.introduction.using">
        <title>Utilisation de Zend_Auth</title>

        <para>
            Deux manières d'utiliser les adaptateurs <classname>Zend_Auth</classname> sont
            proposées&#160;:
        </para>

        <orderedlist>
            <listitem>
                <para>
                    indirectement, via <methodname>Zend_Auth::authenticate()</methodname>&#160;;
                </para>
            </listitem>
            <listitem>
                <para>
                    directement, via la méthode <methodname>authenticate()</methodname> de
                    l'adaptateur.
                </para>
            </listitem>
        </orderedlist>

        <para>
            L'exemple suivant illustre la manière d'utiliser un adaptateur
            <classname>Zend_Auth</classname> de manière indirecte via l'utilisation de la classe
            <classname>Zend_Auth</classname>&#160;:
        </para>

        <programlisting language="php"><![CDATA[
// Obtention d'une référence de l'instance du Singleton de Zend_Auth
$auth = Zend_Auth::getInstance();

// Définition de l'adaptateur d'authentification
$authAdaptateur = new MonAdaptateurAuth($identifiant, $motdepasse);

// Tentative d'authentification et stockage du résultat
$resultat = $auth->authenticate($authAdaptateur);

if (!$resultat->isValid()) {
    // Echec de l'authentification ; afficher pourquoi
    foreach ($resultat->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // Authentification réussie ; l'identité ($identifiant) est
    // stockée dans la session
    // $resultat->getIdentity() === $auth->getIdentity()
    // $resultat->getIdentity() === $identifiant
}
]]></programlisting>

        <para>
            Une fois la tentative d'authentification réalisée, tel que montré ci-dessus, il
            est très simple de vérifier si une identité correctement authentifiée existe&#160;:
        </para>

        <programlisting language="php"><![CDATA[
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // l'identité existe ; on la récupère
    $identite = $auth->getIdentity();
}
]]></programlisting>

        <para>
            Pour retirer une identité du stockage persistant, utilisez simplement la méthode
            <methodname>clearIdentity()</methodname>. A utiliser typiquement pour implémenter une
            opération de déconnexion d'une application&#160;:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Auth::getInstance()->clearIdentity();
]]></programlisting>

        <para>
            Quand l'utilisation automatique du stockage persistant n'est pas appropriée, le
            développeur peut simplement contourner l'utilisation de la classe
            <classname>Zend_Auth</classname> en utilisant directement une classe adaptateur.
            L'usage direct d'une classe adaptateur implique de configurer et préparer l'objet
            adaptateur et d'appeler ensuite sa méthode <methodname>authenticate()</methodname>. Les
            détails spécifiques à un adaptateur sont décrits dans la documentation de chacun
            d'entre-eux. L'exemple suivant utilise directement
            <classname>MonAdaptateurAuth</classname>&#160;:
        </para>

        <programlisting language="php"><![CDATA[
// Définition de l'adaptateur d'authentification
$authAdaptateur = new MonAdaptateurAuth($identifiant, $motdepasse);

// Tentative d'authentification, stockage du résultat
$resultat = $authAdaptateur->authenticate();

if (!$resultat->isValid()) {
    // échec de l'authentification ; afficher pourquoi
    foreach ($resultat->getMessages() as $message) {
        echo "$message\n";
    }
} else {
    // Authentification réussie
    // $resultat->getIdentity() === $identifiant
}
]]></programlisting>
    </sect2>
</sect1>
