Freitag, 31. August 2012

Überlegungen zur Benutzeranmeldung in Web-Anwendungen

Wer eine Web-Anwendung mit PHP entwickelt, die nicht von jedem Internet-Benutzer anonym benutzt werden soll, muss überlegen, wie die Identität des Benutzers überprüft (Authentication) und der Zugriff gegebenenfalls abgelehnt werden kann.

Dafür gibt es zwei gängige Vorgehensweisen.Sie können in der Benutzeroberfläche der Anwendung einen Login-Dialog vorsehen und die Gültigkeit der Anmeldedaten in der Anwendung selbst prüfen oder Sie verwenden die sogenannte HTTP Authentifizierung. Beide Methode haben Vor- und Nachteile.

Eigener Login Dialog
 
Zur Anmeldung wird ein eigener Login-Dialog erzeugt. (Das GGF Framework, die "Contacts" Beispiel-Anwendung und die Gallery des ReinHTML Dialog Designers liefern dafür Vorlagen). Diese speichern per Konvention bei erfolgreicher Anmeldung den User-ID in einer der Variablen $_SESSION['userid']. Somit ist es möglich etwa Benutzer-spezifische Daten anhand der Benutzerkennung auszuwählen. Bei der Definition von Menüs oder Buttons, kann man angeben, dass sie deaktiviert sein sollen, solange kein Benutzer angemeldet ist (Funktion IsLoggedOn() in jeder Window-Klasse). Über eine logoff-Funktion kann einemAbmeldung explizit veranlasst werden. Sobald die PHP Session endet, endet natürlich ebenfalls die Anmeldung.

Natürlich muss man auch verhindern, dass der Login-Dialog einfach umgangen wird etwa indem jemand den URL eines Sub-Fensters manuell eingibt. (Im GGF-Framework wird das zuverlässig und vor allem automatisch verhindert). Der eingebaute Dispatcher lehnt alle URL's ab, die im jeweiligen Kontext nicht erlaubt bzw. sinnvoll sind. Damit ist es nicht möglich, dass der Login-Dialog umgangen und direkt "in die Mitte" einer Anwendung verzweigt wird.

Zu beachten ist, dass HTML Dialoge alle Daten (auch ein Passwort) im HTTP Protokoll unverschlüsselt übertragen. Anwendungen, die mit sensiblen Daten arbeiten sollten daher unbedingt das HTTPS Protokoll verwenden. Damit ist auch die Übertragung der Login-Daten gesichert.

Wie man etwa Apache für HTTPS einrichtet, ist etwa hier beschrieben. Web-Hoster bieten jedoch auch eigene, einfachere Varianten an.

HTTP Authentifizierung

Bei der HTTP Authentifzierung sorgt der Web-Server dafür, dass nur angemeldete Benutzer auf die
Dateien ihrer Anwendung zugreifen können. Beim Zugriff auf ein geschütztes Verzeichnis, fordert der Web-Server vom Client User-ID und Password an. Der Client, also der Web-Browser öffnet daraufhin einen eingebauten Standard-Dialog und fordert den Benutzer zum Login auf.

Der Web-Server prüft dann - nach vorkonfigurierten Methoden (Passwort-Datei, Datenbank Zugriff, LDAP Zugriff etc.) - ob die Anmeldedaten stimmen. Erst dann liefert er das Dokument an den Client aus bzw. führt Server-seitige Skripte (PHP) aus.

Welche Verzeichnisse am Web-Server auf diese Weise geschützt werden sollen und wie die Gültigkeitsprüfung von User-ID und Password erfolgen soll, wird in der Web-Server Konfiguration festgelegt. Die PHP Anwendung hat damit wenig zu tun. Allerdings wird der Name des angemeldeten Benutzers (und einige weitere Information) in der $_SERVER Variablen mitgegeben.

Damit der Benutzer nicht bei jedem Dateizugriff erneut um User-ID und Passwort gefragt werden muss, merkt sich der Web-Browser die Angaben und sendet sie automatisch an den Server wenn weitere Dateien vom Server angefragt werden. Im Normalfall werden User-ID und Passwort so lange gespeichert, bis das Browser-Fenster geschlossen wird. Fast immer bieten die Browser aber auch die Option an, die Information auch permanent in einem Passwort-Cache zu speichern. Das hat für den Benutzer den Vorteil, dass er beim Aufruf der Web-Anwendung seinen User-ID und sein Passwort nie mehr eingeben muß.

Das ist aber auch ein Nachteil. Wenn man seinen Arbeitsplatz verläßt ohne den Zugriff zu sperren, das Browser-Fenster zu schließen oder den Passwort-Cache zu leeren, kann jeder mit Zugang zum angemeldeten Rechner die Web-Anwendung öffnen ohne Userid und Passwort zu kennen, weil eben der Browser die Anmeldung automatisch durchführt. Deshalb verwendet man im Online-Banking die HTTP Authentication nicht. Leider gibt es auch keinen standardisierten Weg, von der Web-Anwendung aus ein Ausloggen des Benutzers zu veranlassen (also den Browser dazu zu bewegen eine Anmeldung zu "vergessen").

Gegenüber "Man-in-the-Middle" Angriffen bietet die HTTP Authentifizierung einen gewissen Schutz, sofern die Variante "Digest" Authentifizierung verwendet wird. Dabei sendet der Client das Passwort verschlüsselt an den Server. Ein "Abhören" der Anmeldedaten (etwa in einem offenen WLAN) wird damit zumindest wesentlich erschwert.

Allerdings sollten sensible Anwendungen ohnehin nur via HTTPS Ptotokoll betrieben werden, weil ja nicht nur das Passwort sondern auch die übertragenen Daten verschlüsselt werden müssen.

Möchte man die HTTP Authentifizierung im GGF Framework nutzen, so muss man  (ab Version 4.4) lediglich die Variable $http_authentication in GGFSetup.php auf TRUE setzen (Wie man den Web-Server konfiguriert, ist in der Datei GGFauthenticate.php beschrieben). Das bewirkt, dass nach erfolgreichem Login (wie bei Applikations-eigenen Login Dislogen) die Benutzerkennung in $_SESSION['userid'] gespeichert ist. Somit ist es auch in dieser Variante möglich etwa Benutzer-spezifische Daten anhand der Benutzerkennung auszuwählen.