File: Zend_Auth_Adapter_DbTable.xml

package info (click to toggle)
zendframework 1.12.9%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 133,584 kB
  • sloc: xml: 1,311,829; php: 570,173; sh: 170; makefile: 125; sql: 121
file content (354 lines) | stat: -rw-r--r-- 15,493 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.auth.adapter.dbtable">
    <title>Authentification avec une table de base de données</title>

    <sect2 id="zend.auth.adapter.dbtable.introduction">
        <title>Introduction</title>

        <para>
            <classname>Zend_Auth_Adapter_DbTable</classname> fournit la possibilité d'authentifier
            sur la base de crédits stockés dans une table de base de données. Comme
            <classname>Zend_Auth_Adapter_DbTable</classname> requiert qu'une instance de
            <classname>Zend_Db_Adapter_Abstract</classname> soit fournie à son constructeur, chaque
            instance est liée à une connexion de base de données particulière. Les autres options
            de configuration peuvent être réglées grâce au constructeur ou au travers de
            différentes méthodes, une pour chaque option.
        </para>

        <para>
            Les options de configuration disponibles incluent&#160;:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis><property>tableName</property></emphasis>&#160;: il s'agit du nom de
                    la table dans la base de données qui contient les crédits d'authentification,
                    et envers laquelle la requête d'authentification sera réalisée.
                </para>
            </listitem>
            <listitem>
                <para>
                    <emphasis><property>identityColumn</property></emphasis>&#160;: il s'agit du
                    nom de la colonne dans la table utilisée pour représenter l'identité. La
                    colonne d'identité doit contenir une valeur unique, comme un "username" ou
                    une adresse mail.
                </para>
            </listitem>
            <listitem>
                <para>
                    <emphasis><property>credentialColumn</property></emphasis>&#160;: il s'agit
                    du nom de la colonne dans la table utilisée pour représenter le crédit. Dans
                    le cas d'une simple authentification par identité / mot de passe, la valeur
                    de crédit correspond au mot de passe. Voir aussi l'option
                    <property>credentialTreatment</property>.
                </para>
            </listitem>
            <listitem>
                <para>
                    <emphasis><property>credentialTreatment</property></emphasis>&#160;: dans la
                    plupart des cas, les mots de passe et autres données sensibles sont cryptés,
                    hachés, encodés, masqués, ou sinon traités à travers une fonction ou un
                    algorithme. En spécifiant un traitement paramétrable de chaîne avec cette
                    méthode, comme <methodname>MD5(?)</methodname> ou
                    <methodname>PASSWORD(?)</methodname>, un
                    développeur peut appliquer un code <acronym>SQL</acronym> arbitraire sur les
                    données de crédit fournies. Comme ces fonctions sont spécifiques à chaque
                    gestionnaire de base de données (<acronym>SGBD</acronym>), vérifiez le manuel
                    de la base de données pour vérifier la disponibilité de ces fonctions dans
                    votre système.
                </para>
            </listitem>
        </itemizedlist>

        <example id="zend.auth.adapter.dbtable.introduction.example.basic_usage">
            <title>Utilisation basique</title>

            <para>
                Comme expliqué dans l'introduction, le constructeur de
                <classname>Zend_Auth_Adapter_DbTable</classname> requiert une instance de
                <classname>Zend_Db_Adapter_Abstract</classname> qui est utilisée comme connexion à
                la base de données à laquelle l'instance d'adaptateur d'authentification est liée.
                Avant tout, la connexion à la base de donnée devrait être crée.
            </para>

            <para>
                Le code suivant crée un adaptateur pour une base de données en mémoire, crée
                un schéma avec une table unique, et insère une ligne sur laquelle nous pouvons
                réaliser une requête d'authentification plus tard. Cet exemple requiert que
                l'extension <acronym>PDO</acronym> SQLite soit disponible&#160;:
            </para>

            <programlisting language="php"><![CDATA[
// Crée une connexion de base de données SQLite en mémoire
$dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' =>
                                                  ':memory:'));

// Construit une requête de création de table
$sqlCreate = 'CREATE TABLE [users] ( '
           . '[id] INTEGER  NOT NULL PRIMARY KEY, '
           . '[username] VARCHAR(50) UNIQUE NOT NULL, '
           . '[password] VARCHAR(32) NULL, '
           . '[real_name] VARCHAR(150) NULL)';

// Crée la table de crédits d'authentification
$dbAdapter->query($sqlCreate);

// Construit la requête pour insérer une ligne pour laquelle
// l'authentification pourra réussir
$sqlInsert = "INSERT INTO users (username, password, real_name) "
           . "VALUES ('my_username', 'my_password', 'My Real Name')";

// Insertion des données
$dbAdapter->query($sqlInsert);
]]></programlisting>

            <para>
                Avec une connexion de base de données et des données disponibles dans la
                table, une instance de <classname>Zend_Auth_Adapter_DbTable</classname> peut être
                créée. Les valeurs d'options de configuration peuvent être fournies au
                constructeur ou en tant que paramètres aux méthodes de réglage après
                l'instanciation&#160;:
            </para>

            <programlisting language="php"><![CDATA[
// Configure une instance avec des paramètres de constructeur ...
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter,
                                             'users',
                                             'username',
                                             'password');

// ... ou configure l'instance avec des méthodes de réglage
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users')
            ->setIdentityColumn('username')
            ->setCredentialColumn('password');
]]></programlisting>

            <para>
                A cet instant, l'instance de l'adaptateur d'authentification est prête à
                recevoir des requêtes d'authentification. Dans le but de réaliser une requête
                d'authentification, les valeurs des crédits requêtés sont fournies à l'adaptateur
                avant d'appeler la méthode <methodname>authenticate()</methodname>&#160;:
            </para>

            <programlisting language="php"><![CDATA[
// Règle les valeurs d'entrées des crédits
// (en général, à partir d'un formulaire d'enregistrement)
$authAdapter->setIdentity('my_username')
            ->setCredential('my_password');

// Réalise la requête d'authentification, et sauvegarde le résultat
$result = $authAdapter->authenticate();
]]></programlisting>

            <para>
                En plus de la disponibilité de la méthode <methodname>getIdentity()</methodname>
                pour récupérer l'objet du résultat d'authentification,
                <classname>Zend_Auth_Adapter_DbTable</classname> supporte aussi la récupération de
                la ligne de la table qui a réussi l'authentification&#160;:
            </para>

            <programlisting language="php"><![CDATA[
// Affiche l'identité
echo $result->getIdentity() . "\n\n";

// Affiche la ligne de résultat
print_r($authAdapter->getResultRowObject());

/* Affiche:
my_username

Array
(
    [id] => 1
    [username] => my_username
    [password] => my_password
    [real_name] => My Real Name
)
*/
]]></programlisting>

            <para>
                Puisque la ligne de la table contient la valeur de crédit, il est important de
                garantir ces valeurs contre l'accès fortuit.
            </para>
        </example>
    </sect2>

    <sect2 id="zend.auth.adapter.dbtable.advanced.storing_result_row">
        <title>Utilisation avancée : maintenir persistant l'objet de résultat DbTable</title>

        <para>
            Par défaut, <classname>Zend_Auth_Adapter_DbTable</classname> retourne l'identité
            fournie à l'objet Auth en cas d'authentification couronnée de succès. Un autre scénario
            d'utilisation, où les développeurs veulent stocker dans le mécanisme de stockage
            persistant du <classname>Zend_Auth</classname> un objet d'identité contenant d'autres
            informations utiles, est résolu en utilisant la méthode
            <methodname>getResultRowObject()</methodname> retournant un objet
            <emphasis>stdClass</emphasis>. Le petit bout de code suivant illustre cette
            utilisation&#160;:
        </para>

        <programlisting language="php"><![CDATA[
// authentifie avec Zend_Auth_Adapter_DbTable
$result = $this->_auth->authenticate($adapter);

if ($result->isValid()) {

    // stocke l'identité comme objet dans lequel seulement username et
    // real_name sont retournés
    $storage = $this->_auth->getStorage();
    $storage->write($adapter->getResultRowObject(array('username',
                                                       'real_name')));

    // stocke l'identité comme objet dans lequel la colonne password
    // a été omis
    $storage->write($adapter->getResultRowObject(null, 'password'));

    /* ... */

} else {

    /* ... */

}
]]></programlisting>
    </sect2>

    <sect2 id="zend.auth.adapter.dbtable.advanced.advanced_usage">
        <title>Utilisation avancée par l'exemple</title>

        <para>
            Bien que le but initial de <classname>Zend_Auth</classname> (et par extension celui de
            <classname>Zend_Auth_Adapter_DbTable</classname>) est principalement
            l'<emphasis>authentification</emphasis> et non
            l'<emphasis>autorisation</emphasis> (ou contrôle d'accès), il existe quelques
            exemples et problèmes qui franchissent la limite des domaines auxquels ils
            appartiennent. Selon la façon dont vous avez décidé d'expliquer votre problème, il
            semble parfois raisonnable de résoudre ce qui pourrait ressembler à un problème
            d'autorisation dans l'adaptateur d'authentification.
        </para>

        <para>
            Ceci étant dit, <classname>Zend_Auth_Adapter_DbTable</classname> possède des mécanismes
            qui sont construits de telle sorte qu'ils peuvent être démultipliés pour ajouter des
            contrôles supplémentaires au moment de l'authentification pour résoudre quelques
            problèmes communs d'utilisateur.
        </para>

        <programlisting language="php"><![CDATA[
// La valeur du champs "etat" d'un compte
// ne doit pas être égal à "compromis"
$adapter = new Zend_Auth_Adapter_DbTable($db,
                                         'utilisateurs',
                                         'login',
                                         'password',
                                         'MD5(?) AND etat != "compromis"');

// La valeur du champs "actif" d'un compte
// doit être égal à "TRUE"
$adapter = new Zend_Auth_Adapter_DbTable($db,
                                         'utilisateurs',
                                         'login',
                                         'password',
                                         'MD5(?) AND actif = "TRUE"');
]]></programlisting>

        <para>
            Un autre scénario possible est l'implantation d'un mécanisme de "salting".
            "Salting" est un terme se référant une technique qui peut fortement améliorer la
            sécurité de votre application. C'est basé sur l'idée que concaténer une chaîne
            aléatoire à tout mot de passe rend impossible la réussite d'une attaque de type "brute
            force" sur la base de données en utilisant des valeurs préalablement hashées issues
            d'un dictionnaire.
        </para>

        <para>
            Par conséquent nous devons modifier notre table pour stocker notre chaîne de
            "salt" aléatoire&#160;:
        </para>

        <programlisting language="php"><![CDATA[
$sqlAlter = "ALTER TABLE [users] "
          . "ADD COLUMN [password_salt] "
          . "AFTER [password]";

$dbAdapter->query($sqlAlter);
]]></programlisting>

        <para>
            Voici une méthode simple pour générer une chaîne aléatoire pour chaque
            utilisateur à leur enregistrement&#160;:
        </para>

        <programlisting language="php"><![CDATA[
for ($i = 0; $i < 50; $i++)
{
    $dynamicSalt .= chr(rand(33, 126));
}
]]></programlisting>

        <para>Et maintenant, construisons l'adaptateur&#160;:</para>

        <programlisting language="php"><![CDATA[
$adapter = new Zend_Auth_Adapter_DbTable(
    $db,
    'users',
    'username',
    'password',
    "MD5(CONCAT('"
    . Zend_Registry::get('staticSalt')
    . "', ?, password_salt))"
);
]]></programlisting>

        <note>
            <para>
                Vous pouvez encore améliorer la sécurité en utilisant une chaîne de "salt"
                statique codée en dur dans votre application. Dans le cas ou la base de données est
                compromise (par exemple par une attaque de type injection <acronym>SQL</acronym>)
                mais que votre serveur Web est intact, les données sont inutilisables par
                l'attaquant.
            </para>
        </note>

        <para>
            Une autre alternative est d'utiliser la méthode <methodname>getDbSelect()</methodname>
            de la classe <classname>Zend_Auth_Adapter_DbTable</classname> après la construction de
            l'adaptateur. Cette méthode retournera une instance d'objet
            <classname>Zend_Db_Select</classname> utilisée pour réaliser la routine
            <methodname>authenticate()</methodname>. Il est important de noter que cette méthode
            retournera toujours le même objet, que la méthode
            <methodname>authenticate()</methodname> a été appelée ou non. Cet objet
            <emphasis>ne comportera aucune</emphasis> information d'identité ou de crédit puisque
            celles-ci sont placées dans l'objet select au moment de
            <methodname>authenticate()</methodname>.
        </para>

        <para>
            Un exemple de situation nécessitant l'utilisation de la méthode
            <methodname>getDbSelect()</methodname> serait de vérifier le statut d'un utilisateur,
            en d'autres termes pour voir si le compte d'un utilisateur est activé.
        </para>
        <programlisting language="php"><![CDATA[
// En continuant avec l'exemple ci-dessus
$adapter = new Zend_Auth_Adapter_DbTable(
    $db,
    'users',
    'username',
    'password',
    'MD5(?)'
);

// Récupérer l'objet select (par référence)
$select = $adapter->getDbSelect();
$select->where('active = "TRUE"');

// Authentification, ceci s'assure que users.active = TRUE
$adapter->authenticate();
]]></programlisting>
    </sect2>
</sect1>