Datenbanktabellen Authentifizierung
Einführung
Zend_Auth_Adapter_DbTable bietet die Möglichkeit sich gegenüber Zeugnissen zu
authentifizieren die in einer Datenbank Tabelle gespeichert sind. Weil
Zend_Auth_Adapter_DbTable eine Instanz von Zend_Db_Adapter_Abstract
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.
Die vorhandenen Konfigurationsoptionen beinhalten:
tableName: Das ist der Name der Datenbanktabelle welche die Authentifikations
Zeugnisse enthält, und gegen die die Datenbank Authentifikations Abfrage durchgeführt
wird.
identityColumn: Ist der Name der Spalte der Datenbanktabelle die die
Identität repräsentiert. Die Spalte der Identität muß eindeutige und einmalige Werte
enthalten, wie einen Benutzernamen oder eine Email Adresse.
credentialColumn: 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 credentialTreatment Option.
credentialTreatment: 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 'MD5(?)'
oder 'PASSWORD(?)', könnte ein Entwickler beliebiges SQL an den Eingabe-
Zeugnis-Daten anwenden. Da diese Funktionen der darunter liegenden RDBMS speziell
gehören, sollte das Handbuch der Datenbank auf das Vorhandensein solcher Funktionen
im eigenen Datenbank System geprüft werden.
Grundsätzliche Verwendung
Wie bereits in der Einführung beschrieben benötigt der Zend_Auth_Adapter_DbTable
Konstruktor eine Instanz von Zend_Db_Adapter_Abstract die als Datenbank Verbindung
fungiert zu welcher die Instanz des Authentifizierungs-Adapters gebunden ist. Zuerst sollte die
Datenbankverbindung erstellt werden.
Der folgende Code erstellt eien 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 SQLite Erweiterung:
':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);
]]>
Mit der Datenbankverbindung und den vorhandenen Tabellendaten, kann eine Instanz von
Zend_Auth_Adapter_DbTable erstellt werden. Die Werte der Konfigurationsoptionen
können dem Konstruktor übergeben werden, oder als Parameter der setzenden Methoden nach der
Instanziierung:
setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password')
;
]]>
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 authenticate() Methode, übergeben:
setIdentity('my_username')
->setCredential('my_password');
// Die Authentifizierungsabfrage durchführen, das Ergebnis speichern
$result = $authAdapter->authenticate();
]]>
Zusätzlich zum Vorhandensein der getIdentity() Methode über das Authentifizierungs
Ergebnisobjekt, unterstützt Zend_Auth_Adapter_DbTable auch das empfangen der
Tabellenzeile wenn die Authentifizierung erfolgeich war:
getIdentity() . "\n\n";
// Die Ergebniszeile ausgeben
print_r($identity);
/* Ausgabe:
my_username
Array
(
[id] => 1
[username] => my_username
[password] => my_password
[real_name] => My Real Name
)
*/
]]>
Da die Zeile der Tabelle die Zeugnis Daten enthält ist es wichtig diese Werte gegenüber
unberechtigten Versuchen abzusichern.
Fortgeschrittene Verwendung: Ein DbTable Ergebnis Objekt dauerhaft machen
Standardmäßig gibt Zend_Auth_Adapter_DbTable 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 Zend_Auth abspeichern wollen, wird durch die Verwendung der
getResultRowObject() Methode gelöst die ein stdClass Objekt zurück gibt.
Der folgende Code Abschnitt zeigt diese Verwendung:
_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 {
/* ... */
}
]]>
Forgeschrittene Verwendung durch Beispiele
Wärend der primäre Zweck von Zend_Auth (und konsequenter Weise
Zend_Auth_Adapter_DbTable) die Authentifizierung
und nicht die Authorisierung 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.
Mit dieser Definition, hat Zend_Auth_Adapter_DbTable einige eingebaute
Mechanismen die für zusätzliche Checks wärend der Authentifizierungszeit angepasst
werden können, um einige übliche Benutzerprobleme zu lösen.
Ein anderes Szenario kann die Implementierung eines Saltingmachanismus sein. Salting ist ein
Ausdruck der auf eine Technik verweist die die Sicherheit der Anwendung sehr stark erhöht.
Sie basiert auf der Idee das 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.
Hierfür muß die Tabelle so modifiziert werden das Sie unseren Salt-String enthält:
query($sqlAlter);
]]>
Hier ist ein einfacher Weg um einen Salt String für jeden Benutzer bei der Registrierung zu
erstellen:
Und nun erstellen wir den Adapter:
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
SQL Injection Attacke) aber der Webserver intakt bleibt sind die Daten für den Angreifer noch
immer nicht verwendbar.
Eine andere Alternative besteht darin die getDbSelect() Methode von
Zend_Auth_Adapter_DbTable zu verwenden nachdem der Adapter erstellt wurde. Diese
Methode gibt die Instanz des Zend_Db_Select Objekts zurück welches verwendet wird
um die authenticate() Methode zu komplettieren. Es ist wichtig anzumerken das diese
Methode immer das gleiche Objekt zurückgibt unabhängig davon ob authenticate()
aufgerufen wurde oder nicht. Diese Objekt enthält keine Identity
oder Anmeldeinformationen in sich da diese Werte im Select Objekt wärend des Ausführens
von authenticate() platziert werden.
Als Beispiel einer Situation könnte man die getDbSelect() Methode verwenden um
den Status eines Benutzers zu prüfen, in anderen Worten sehen ob der Account des
Benutzers aktiviert ist.
getDbSelect();
$select->where('active = "TRUE"');
// Authentifizieren, das stellt sicher das users.active = TRUE
$adapter->authenticate();
]]>