Zend_Auth_Adapter_DbTable.xml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15860 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.auth.adapter.dbtable">
  5. <title>Datenbanktabellen Authentifizierung</title>
  6. <sect2 id="zend.auth.adapter.dbtable.introduction">
  7. <title>Einführung</title>
  8. <para>
  9. <classname>Zend_Auth_Adapter_DbTable</classname> bietet die Möglichkeit sich gegenüber
  10. Zeugnissen zu authentifizieren die in einer Datenbank Tabelle gespeichert sind. Weil
  11. <classname>Zend_Auth_Adapter_DbTable</classname> eine Instanz von
  12. <classname>Zend_Db_Adapter_Abstract</classname> benötigt, die an den Konstruktor
  13. übergeben wird, ist jede Instanz an eine spezielle Datenbank Verbindung verknüpft.
  14. Andere Konfigurationsoptionen können durch den Konstruktor gesetzt werden und durch die
  15. Methoden der Instanz. Eine für jede Option.
  16. </para>
  17. <para>
  18. Die vorhandenen Konfigurationsoptionen beinhalten:
  19. </para>
  20. <itemizedlist>
  21. <listitem>
  22. <para>
  23. <emphasis>tableName</emphasis>: Das ist der Name der Datenbanktabelle
  24. welche die Authentifikations Zeugnisse enthält, und gegen die die
  25. Datenbank Authentifikations Abfrage durchgeführt wird.
  26. </para>
  27. </listitem>
  28. <listitem>
  29. <para>
  30. <emphasis>identityColumn</emphasis>: Ist der Name der Spalte der
  31. Datenbanktabelle die die Identität repräsentiert. Die Spalte der Identität
  32. muß eindeutige und einmalige Werte enthalten, wie einen Benutzernamen oder
  33. eine Email Adresse.
  34. </para>
  35. </listitem>
  36. <listitem>
  37. <para>
  38. <emphasis>credentialColumn</emphasis>: Das ist der Name der Spalte der
  39. Datenbanktabelle die verwendet wird um die Zeugnisse zu repräsentieren. Bei
  40. einem einfachen Identitäts und Passwort-Authentifizierungs Schema
  41. korrespondieren die Zeugnisse mit dem Passwort. Siehe auch die
  42. <emphasis>credentialTreatment</emphasis> Option.
  43. </para>
  44. </listitem>
  45. <listitem>
  46. <para>
  47. <emphasis>credentialTreatment</emphasis>: In vielen Fällen sind Passwörter
  48. und andere sensitive Daten verschlüsselt, gehasht, kodiert, gesalted,
  49. verschleiert oder auf andere Weise durch irgendeine Funktion oder einen
  50. Algorithmus behandelt. Durch die Spezifikation eines parametrisierbaren
  51. Behandlungsstrings mit dieser Methode, wie 'MD5(?)' oder
  52. 'PASSWORD(?)', könnte ein Entwickler beliebiges SQL an den
  53. Eingabe- Zeugnis-Daten anwenden. Da diese Funktionen der darunter liegenden
  54. RDBMS speziell gehören, sollte das Handbuch der Datenbank auf das
  55. Vorhandensein solcher Funktionen im eigenen Datenbank System geprüft werden.
  56. </para>
  57. </listitem>
  58. </itemizedlist>
  59. <example id="zend.auth.adapter.dbtable.introduction.example.basic_usage">
  60. <title>Grundsätzliche Verwendung</title>
  61. <para>
  62. Wie bereits in der Einführung beschrieben benötigt der
  63. <classname>Zend_Auth_Adapter_DbTable</classname> Konstruktor eine Instanz von
  64. <classname>Zend_Db_Adapter_Abstract</classname> die als Datenbank Verbindung
  65. fungiert zu welcher die Instanz des Authentifizierungs-Adapters gebunden ist. Zuerst
  66. sollte die Datenbankverbindung erstellt werden.
  67. </para>
  68. <para>
  69. Der folgende Code erstellt einen Adapter für eine In-Memory Datenbank, erstellt ein
  70. einfaches Datenbankschema, und fügt eine Zeile ein gegen die später eine
  71. Authentifizierungs-Abfrage durchgeführt werden kann. Dieses Beispiel benötigt die
  72. SQLite Erweiterung:
  73. </para>
  74. <programlisting language="php"><![CDATA[
  75. // Erstellt eine In-Memory SQLite Datenbankverbindung
  76. $dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' =>
  77. ':memory:'));
  78. // Erstellt eine einfache Datenbank-Erstellungs-Abfrage
  79. $sqlCreate = 'CREATE TABLE [users] ('
  80. . '[id] INTEGER NOT NULL PRIMARY KEY, '
  81. . '[username] VARCHAR(50) UNIQUE NOT NULL, '
  82. . '[password] VARCHAR(32) NULL, '
  83. . '[real_name] VARCHAR(150) NULL)';
  84. // Erstellt die Tabelle für die Authentifizierungs Zeugnisse
  85. $dbAdapter->query($sqlCreate);
  86. // Erstellt eine Abfrage um eine Zeile einzufügen für die eine
  87. // Authentifizierung erfolgreich sein kann
  88. $sqlInsert = "INSERT INTO users (username, password, real_name) "
  89. . "VALUES ('my_username', 'my_password', 'My Real Name')";
  90. // Daten einfügen
  91. $dbAdapter->query($sqlInsert);
  92. ]]></programlisting>
  93. <para>
  94. Mit der Datenbankverbindung und den vorhandenen Tabellendaten, kann eine Instanz von
  95. <classname>Zend_Auth_Adapter_DbTable</classname> erstellt werden. Die Werte der
  96. Konfigurationsoptionen können dem Konstruktor übergeben werden, oder als Parameter
  97. der setzenden Methoden nach der Instanziierung:
  98. </para>
  99. <programlisting language="php"><![CDATA[
  100. // Die Instanz mit Konstruktor Parametern konfiurieren...
  101. $authAdapter = new Zend_Auth_Adapter_DbTable(
  102. $dbAdapter,
  103. 'users',
  104. 'username',
  105. 'password'
  106. );
  107. // ...oder die Instanz mit den setzenden Methoden konfigurieren
  108. $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
  109. $authAdapter
  110. ->setTableName('users')
  111. ->setIdentityColumn('username')
  112. ->setCredentialColumn('password');
  113. ]]></programlisting>
  114. <para>
  115. An diesem Punkt ist die Instanz des Authentifizierungsadapters bereit um
  116. Authentifierungsabfragen zu akzeptieren. Um eine Authentifierungsabfrage zu
  117. formulieren, werden die Eingabezeugnis Werte dem Adapter vor dem Aufruf der
  118. <methodname>authenticate()</methodname> Methode, übergeben:
  119. </para>
  120. <programlisting language="php"><![CDATA[
  121. // Die Eingabezeugnis Werte setzen (z.B. von einem Login Formular)
  122. $authAdapter
  123. ->setIdentity('my_username')
  124. ->setCredential('my_password');
  125. // Die Authentifizierungsabfrage durchführen, das Ergebnis speichern
  126. $result = $authAdapter->authenticate();
  127. ]]></programlisting>
  128. <para>
  129. Zusätzlich zum Vorhandensein der <methodname>getIdentity()</methodname> Methode
  130. über das Authentifizierungs Ergebnisobjekt, unterstützt
  131. <classname>Zend_Auth_Adapter_DbTable</classname> auch das empfangen der
  132. Tabellenzeile wenn die Authentifizierung erfolgeich war:
  133. </para>
  134. <programlisting language="php"><![CDATA[
  135. // Die Identität ausgeben
  136. echo $result->getIdentity() . "\n\n";
  137. // Die Ergebniszeile ausgeben
  138. print_r($identity);
  139. /* Ausgabe:
  140. my_username
  141. Array
  142. (
  143. [id] => 1
  144. [username] => my_username
  145. [password] => my_password
  146. [real_name] => My Real Name
  147. )
  148. */
  149. ]]></programlisting>
  150. <para>
  151. Da die Zeile der Tabelle die Zeugnis Daten enthält ist es wichtig diese Werte
  152. gegenüber unberechtigten Versuchen abzusichern.
  153. </para>
  154. </example>
  155. </sect2>
  156. <sect2 id="zend.auth.adapter.dbtable.advanced.storing_result_row">
  157. <title>Fortgeschrittene Verwendung: Ein DbTable Ergebnis Objekt dauerhaft machen</title>
  158. <para>
  159. Standardmäßig gibt <classname>Zend_Auth_Adapter_DbTable</classname> die unterstützte
  160. Identität an das Auth Objekt bei erfolgreicher Authentifizierung zurück. Ein anderes
  161. Verwendungs-Szenario, bei dem Entwickler ein Identitäts Objekt, welches andere nützliche
  162. Informationen enthält, in den dauerhaften Speichermechanismus von
  163. <classname>Zend_Auth</classname> abspeichern wollen, wird durch die Verwendung der
  164. <methodname>getResultRowObject()</methodname> Methode gelöst die ein
  165. <emphasis>stdClass</emphasis> Objekt zurück gibt. Der folgende Code Abschnitt zeigt
  166. diese Verwendung:
  167. </para>
  168. <programlisting language="php"><![CDATA[
  169. // Mit Zend_Auth_Adapter_DbTable authentifizieren
  170. $result = $this->_auth->authenticate($adapter);
  171. if ($result->isValid()) {
  172. // Die Identität als Objekt speichern wobei nur der Benutzername und
  173. // der echte Name zurückgegeben werden
  174. $storage = $this->_auth->getStorage();
  175. $storage->write($adapter->getResultRowObject(array(
  176. 'username',
  177. 'real_name'
  178. )));
  179. // Die Identität als Objekt speichern, wobei die
  180. // Passwort Spalte unterdrückt wird
  181. $storage->write($adapter->getResultRowObject(
  182. null,
  183. 'password'
  184. ));
  185. /* ... */
  186. } else {
  187. /* ... */
  188. }
  189. ]]></programlisting>
  190. </sect2>
  191. <sect2 id="zend.auth.adapter.dbtable.advanced.advanced_usage">
  192. <title>Forgeschrittene Verwendung durch Beispiele</title>
  193. <para>
  194. Wärend der primäre Zweck von <classname>Zend_Auth</classname> (und konsequenter Weise
  195. <classname>Zend_Auth_Adapter_DbTable</classname>) die
  196. <emphasis>Authentifizierung</emphasis> und nicht die <emphasis>Authorisierung</emphasis>
  197. ist, gibt es ein paar Instanzen und Probleme auf dem Weg welche Art besser passt.
  198. Abhängig davon wie man sich entscheidet ein Problem zu beschreiben, macht es manchmal
  199. Sinn, das was wie ein Authorisierungsproblem aussieht im Authentifizierungs-Adapter zu
  200. lösen.
  201. </para>
  202. <para>
  203. Mit dieser Definition, hat <classname>Zend_Auth_Adapter_DbTable</classname> einige
  204. eingebaute Mechanismen die für zusätzliche Checks wärend der Authentifizierungszeit
  205. angepasst werden können, um einige übliche Benutzerprobleme zu lösen.
  206. </para>
  207. <programlisting language="php"><![CDATA[
  208. // Der Feldwert des Status eines Accounts ist nicht gleich "compromised"
  209. $adapter = new Zend_Auth_Adapter_DbTable(
  210. $db,
  211. 'users',
  212. 'username',
  213. 'password',
  214. 'MD5(?) AND status != "compromised"'
  215. );
  216. // Der aktive Feldwert des Accounts ist gleich "TRUE"
  217. $adapter = new Zend_Auth_Adapter_DbTable(
  218. $db,
  219. 'users',
  220. 'username',
  221. 'password',
  222. 'MD5(?) AND active = "TRUE"'
  223. );
  224. ]]></programlisting>
  225. <para>
  226. Ein anderes Szenario kann die Implementierung eines Saltingmachanismus sein. Salting
  227. ist ein Ausdruck der auf eine Technik verweist die die Sicherheit der Anwendung sehr
  228. stark erhöht. Sie basiert auf der Idee das das Anfügen von zufälligen Strings bei jedem
  229. Passwort es unmöglich macht eine erfolgreiche Brute-Force Attacke auf die Datenbank
  230. durchzuführen bei der vorberechnete Hashwerte aus einem Verzeichnis genommen werden.
  231. </para>
  232. <para>
  233. Hierfür muß die Tabelle so modifiziert werden das Sie unseren Salt-String enthält:
  234. </para>
  235. <programlisting language="php"><![CDATA[
  236. $sqlAlter = "ALTER TABLE [users] "
  237. . "ADD COLUMN [password_salt] "
  238. . "AFTER [password]";
  239. $dbAdapter->query($sqlAlter);
  240. ]]></programlisting>
  241. <para>
  242. Hier ist ein einfacher Weg um einen Salt String für jeden Benutzer bei der Registrierung
  243. zu erstellen:
  244. </para>
  245. <programlisting language="php"><![CDATA[
  246. for ($i = 0; $i < 50; $i++) {
  247. $dynamicSalt .= chr(rand(33, 126));
  248. }
  249. ]]></programlisting>
  250. <para>
  251. Und nun erstellen wir den Adapter:
  252. </para>
  253. <programlisting language="php"><![CDATA[
  254. $adapter = new Zend_Auth_Adapter_DbTable(
  255. $db,
  256. 'users',
  257. 'username',
  258. 'password',
  259. "MD5(CONCAT('"
  260. . Zend_Registry::get('staticSalt')
  261. . "', ?, password_salt))"
  262. );
  263. ]]></programlisting>
  264. <note>
  265. <para>
  266. Die Sicherheit kann sogar noch mehr erhöht werden indem ein statischer Salt Wert
  267. hardcoded in der Anwendung verwendet wird. Im Falle das die Datenbank korrumpiert
  268. wird (z.B. durch eine <acronym>SQL</acronym> Injection Attacke) aber der Webserver
  269. intakt bleibt sind die Daten für den Angreifer noch immer nicht verwendbar.
  270. </para>
  271. </note>
  272. <para>
  273. Eine andere Alternative besteht darin die <methodname>getDbSelect()</methodname>
  274. Methode von <classname>Zend_Auth_Adapter_DbTable</classname> zu verwenden nachdem der
  275. Adapter erstellt wurde. Diese Methode gibt die Instanz des
  276. <classname>Zend_Db_Select</classname> Objekts zurück welches verwendet wird um die
  277. <methodname>authenticate()</methodname> Methode zu komplettieren. Es ist wichtig
  278. anzumerken das diese Methode immer das gleiche Objekt zurückgibt unabhängig davon ob
  279. <methodname>authenticate()</methodname> aufgerufen wurde oder nicht. Diese Objekt
  280. <emphasis>enthält keine</emphasis> Identity oder Anmeldeinformationen in sich da diese
  281. Werte im Select Objekt wärend des Ausführens von
  282. <methodname>authenticate()</methodname> platziert werden.
  283. </para>
  284. <para>
  285. Als Beispiel einer Situation könnte man die getDbSelect() Methode verwenden um
  286. den Status eines Benutzers zu prüfen, in anderen Worten sehen ob der Account des
  287. Benutzers aktiviert ist.
  288. </para>
  289. <programlisting language="php"><![CDATA[
  290. // Das Beispiel von oben weiterführen
  291. $adapter = new Zend_Auth_Adapter_DbTable(
  292. $db,
  293. 'users',
  294. 'username',
  295. 'password',
  296. 'MD5(?)'
  297. );
  298. // Das Select Objekt (durch Referenz) bekommen
  299. $select = $adapter->getDbSelect();
  300. $select->where('active = "TRUE"');
  301. // Authentifizieren, das stellt sicher das users.active = TRUE
  302. $adapter->authenticate();
  303. ]]></programlisting>
  304. </sect2>
  305. </sect1>
  306. <!--
  307. vim:se ts=4 sw=4 et:
  308. -->