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 (362 lines) | stat: -rw-r--r-- 14,697 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
355
356
357
358
359
360
361
362
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.auth.adapter.dbtable">
    <title>Datenbanktabellen Authentifizierung</title>

    <sect2 id="zend.auth.adapter.dbtable.introduction">
        <title>Einführung</title>

        <para>
            <classname>Zend_Auth_Adapter_DbTable</classname> bietet die Möglichkeit sich gegenüber
            Zeugnissen zu authentifizieren die in einer Datenbank Tabelle gespeichert sind. Weil
            <classname>Zend_Auth_Adapter_DbTable</classname> eine Instanz von
            <classname>Zend_Db_Adapter_Abstract</classname> benötigt, die an den Konstruktor
            übergeben wird, ist jede Instanz an eine spezielle Datenbank Verbindung verknüpft.
            Andere Konfigurationsoptionen können durch den Konstruktor gesetzt werden und durch die
            Methoden der Instanz. Eine für jede Option.
        </para>

        <para>
            Die vorhandenen Konfigurationsoptionen beinhalten:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis><property>tableName</property></emphasis>: Das ist der Name der
                    Datenbanktabelle welche die Authentifikations Zeugnisse enthält, und gegen die
                    jene Datenbank Authentifikations Abfrage durchgeführt wird.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>identityColumn</property></emphasis>: Ist der Name der
                    Spalte der Datenbanktabelle welche die Identität repräsentiert. Die Spalte der
                    Identität muß eindeutige und einmalige Werte enthalten, wie einen Benutzernamen
                    oder eine Email Adresse.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>credentialColumn</property></emphasis>: Das ist der Name
                    der Spalte der Datenbanktabelle die verwendet wird um die Zeugnisse zu
                    repräsentieren. Bei einem einfachen Identitäts und Passwort-Authentifizierungs
                    Schema korrespondieren die Zeugnisse mit dem Passwort. Siehe auch die
                    <property>credentialTreatment</property> Option.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>credentialTreatment</property></emphasis>: In vielen Fällen
                    sind Passwörter und andere sensitive Daten verschlüsselt, gehasht, kodiert,
                    gesalted, verschleiert oder auf andere Weise durch irgendeine Funktion oder
                    einen Algorithmus behandelt. Durch die Spezifikation eines parametrisierbaren
                    Behandlungsstrings mit dieser Methode, wie '<methodname>MD5(?)</methodname>'
                    oder '<methodname>PASSWORD(?)</methodname>', könnte ein Entwickler beliebiges
                    <acronym>SQL</acronym> an den Eingabe- Zeugnis-Daten anwenden. Da diese
                    Funktionen der darunter liegenden <acronym>RDBMS</acronym> speziell gehören,
                    sollte das Handbuch der Datenbank auf das Vorhandensein solcher Funktionen im
                    eigenen Datenbank System geprüft werden.
                </para>
            </listitem>
        </itemizedlist>

        <example id="zend.auth.adapter.dbtable.introduction.example.basic_usage">
            <title>Grundsätzliche Verwendung</title>

            <para>
                Wie bereits in der Einführung beschrieben benötigt der
                <classname>Zend_Auth_Adapter_DbTable</classname> Konstruktor eine Instanz von
                <classname>Zend_Db_Adapter_Abstract</classname> die als Datenbank Verbindung
                fungiert zu welcher die Instanz des Authentifizierungs-Adapters gebunden ist. Zuerst
                sollte die Datenbankverbindung erstellt werden.
            </para>

            <para>
                Der folgende Code erstellt einen Adapter für eine In-Memory Datenbank, erstellt ein
                einfaches Datenbankschema, und fügt eine Zeile ein gegen die später eine
                Authentifizierungs-Abfrage durchgeführt werden kann. Dieses Beispiel benötigt die
                <acronym>PDO</acronym> SQLite Erweiterung:
            </para>

            <programlisting language="php"><![CDATA[
// Erstellt eine In-Memory SQLite Datenbankverbindung
$dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' =>
                                                  ':memory:'));

// Erstellt eine einfache Datenbank-Erstellungs-Abfrage
$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)';

// Erstellt die Tabelle für die Authentifizierungs Zeugnisse
$dbAdapter->query($sqlCreate);

// Erstellt eine Abfrage um eine Zeile einzufügen für die eine
// Authentifizierung erfolgreich sein kann
$sqlInsert = "INSERT INTO users (username, password, real_name) "
           . "VALUES ('my_username', 'my_password', 'My Real Name')";

// Daten einfügen
$dbAdapter->query($sqlInsert);
]]></programlisting>

            <para>
                Mit der Datenbankverbindung und den vorhandenen Tabellendaten, kann eine Instanz von
                <classname>Zend_Auth_Adapter_DbTable</classname> erstellt werden. Die Werte der
                Konfigurationsoptionen können dem Konstruktor übergeben werden, oder als Parameter
                der setzenden Methoden nach der Instanziierung:
            </para>

            <programlisting language="php"><![CDATA[
// Die Instanz mit Konstruktor Parametern konfiurieren...
$authAdapter = new Zend_Auth_Adapter_DbTable(
    $dbAdapter,
    'users',
    'username',
    'password'
);

// ...oder die Instanz mit den setzenden Methoden konfigurieren
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter
    ->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');
]]></programlisting>

            <para>
                An diesem Punkt ist die Instanz des Authentifizierungsadapters bereit um
                Authentifierungsabfragen zu akzeptieren. Um eine Authentifierungsabfrage zu
                formulieren, werden die Eingabezeugnis Werte dem Adapter vor dem Aufruf der
                <methodname>authenticate()</methodname> Methode, übergeben:
            </para>

            <programlisting language="php"><![CDATA[
// Die Eingabezeugnis Werte setzen (z.B. von einem Login Formular)
$authAdapter
    ->setIdentity('my_username')
    ->setCredential('my_password');

// Die Authentifizierungsabfrage durchführen, das Ergebnis speichern
$result = $authAdapter->authenticate();
]]></programlisting>

            <para>
                Zusätzlich zum Vorhandensein der <methodname>getIdentity()</methodname> Methode
                über das Authentifizierungs Ergebnisobjekt, unterstützt
                <classname>Zend_Auth_Adapter_DbTable</classname> auch das empfangen der
                Tabellenzeile wenn die Authentifizierung erfolgeich war:
            </para>

            <programlisting language="php"><![CDATA[
// Die Identität ausgeben
echo $result->getIdentity() . "\n\n";

// Die Ergebniszeile ausgeben
print_r($$authAdapter->getResultRowObject());

/* Ausgabe:
my_username

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

            <para>
                Da die Zeile der Tabelle die Zeugnis Daten enthält ist es wichtig diese Werte
                gegenüber unberechtigten Versuchen abzusichern.
            </para>
        </example>
    </sect2>

    <sect2 id="zend.auth.adapter.dbtable.advanced.storing_result_row">
        <title>Fortgeschrittene Verwendung: Ein DbTable Ergebnis Objekt dauerhaft machen</title>

        <para>
            Standardmäßig gibt <classname>Zend_Auth_Adapter_DbTable</classname> die unterstützte
            Identität an das Auth Objekt bei erfolgreicher Authentifizierung zurück. Ein anderes
            Verwendungs-Szenario, bei dem Entwickler ein Identitäts Objekt, welches andere nützliche
            Informationen enthält, in den dauerhaften Speichermechanismus von
            <classname>Zend_Auth</classname> abspeichern wollen, wird durch die Verwendung der
            <methodname>getResultRowObject()</methodname> Methode gelöst die ein
            <emphasis>stdClass</emphasis> Objekt zurück gibt. Der folgende Code Abschnitt zeigt
            diese Verwendung:
        </para>

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

if ($result->isValid()) {

    // Die Identität als Objekt speichern wobei nur der Benutzername und
    // der echte Name zurückgegeben werden
    $storage = $this->_auth->getStorage();
    $storage->write($adapter->getResultRowObject(array(
        'username',
        'real_name'
    )));

    // Die Identität als Objekt speichern, wobei die
    // Passwort Spalte unterdrückt wird
    $storage->write($adapter->getResultRowObject(
        null,
        'password'
    ));

    /* ... */

} else {

    /* ... */

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

    <sect2 id="zend.auth.adapter.dbtable.advanced.advanced_usage">
        <title>Fortgeschrittene Verwendung durch Beispiele</title>

        <para>
            Wärend der primäre Zweck von <classname>Zend_Auth</classname> (und konsequenter Weise
            <classname>Zend_Auth_Adapter_DbTable</classname>) die
            <emphasis>Authentifizierung</emphasis> und nicht die <emphasis>Authorisierung</emphasis>
            ist, gibt es ein paar Instanzen und Probleme auf dem Weg welche Art besser passt.
            Abhängig davon wie man sich entscheidet ein Problem zu beschreiben, macht es manchmal
            Sinn, das was wie ein Authorisierungsproblem aussieht im Authentifizierungs-Adapter zu
            lösen.
        </para>

        <para>
            Mit dieser Definition, hat <classname>Zend_Auth_Adapter_DbTable</classname> einige
            eingebaute Mechanismen die für zusätzliche Checks während der Authentifizierungszeit
            angepasst werden können, um einige übliche Benutzerprobleme zu lösen.
        </para>

        <programlisting language="php"><![CDATA[
// Der Feldwert des Status eines Accounts ist nicht gleich "compromised"
$adapter = new Zend_Auth_Adapter_DbTable(
    $db,
    'users',
    'username',
    'password',
    'MD5(?) AND status != "compromised"'
);

// Der aktive Feldwert des Accounts ist gleich "TRUE"
$adapter = new Zend_Auth_Adapter_DbTable(
    $db,
    'users',
    'username',
    'password',
    'MD5(?) AND active = "TRUE"'
);
]]></programlisting>

        <para>
            Ein anderes Szenario kann die Implementierung eines Saltingmachanismus sein. Salting
            ist ein Ausdruck der auf eine Technik verweist welche die Sicherheit der Anwendung sehr
            stark erhöht. Sie basiert auf der Idee dass das Anfügen von zufälligen Strings bei jedem
            Passwort es unmöglich macht eine erfolgreiche Brute-Force Attacke auf die Datenbank
            durchzuführen bei der vorberechnete Hashwerte aus einem Verzeichnis genommen werden.
        </para>

        <para>
            Hierfür muß die Tabelle so modifiziert werden das Sie unseren Salt-String enthält:
        </para>

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

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

        <para>
            Hier ist ein einfacher Weg um einen Salt String für jeden Benutzer bei der Registrierung
            zu erstellen:
        </para>

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

        <para>
            Und nun erstellen wir den Adapter:
        </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>
                Die Sicherheit kann sogar noch mehr erhöht werden indem ein statischer Salt Wert
                hardcoded in der Anwendung verwendet wird. Im Falle das die Datenbank korrumpiert
                wird (z.B. durch eine <acronym>SQL</acronym> Injection Attacke) aber der Webserver
                intakt bleibt sind die Daten für den Angreifer noch immer nicht verwendbar.
            </para>
        </note>

        <para>
            Eine andere Alternative besteht darin die <methodname>getDbSelect()</methodname>
            Methode von <classname>Zend_Auth_Adapter_DbTable</classname> zu verwenden nachdem der
            Adapter erstellt wurde. Diese Methode gibt die Instanz des
            <classname>Zend_Db_Select</classname> Objekts zurück welches verwendet wird um die
            <methodname>authenticate()</methodname> Methode zu komplettieren. Es ist wichtig
            anzumerken das diese Methode immer das gleiche Objekt zurückgibt unabhängig davon ob
            <methodname>authenticate()</methodname> aufgerufen wurde oder nicht. Diese Objekt
            <emphasis>enthält keine</emphasis> Identity oder Anmeldeinformationen in sich da diese
            Werte im Select Objekt während des Ausführens von
            <methodname>authenticate()</methodname> platziert werden.
        </para>

        <para>
            Als Beispiel einer Situation könnte man die <methodname>getDbSelect()</methodname>
            Methode verwenden um den Status eines Benutzers zu prüfen, in anderen Worten sehen ob
            der Account des Benutzers aktiviert ist.
        </para>

        <programlisting language="php"><![CDATA[
// Das Beispiel von oben weiterführen
$adapter = new Zend_Auth_Adapter_DbTable(
    $db,
    'users',
    'username',
    'password',
    'MD5(?)'
);

// Das Select Objekt (durch Referenz) bekommen
$select = $adapter->getDbSelect();
$select->where('active = "TRUE"');

// Authentifizieren, das stellt sicher das users.active = TRUE
$adapter->authenticate();
]]></programlisting>
    </sect2>
</sect1>