| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- <?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>
|