Login Abfrage via Ajax
Ajax ist kann in vielen Web Komponenten enthalten sein, warum also nicht bei einer Login Komponente. Bisher wurde dieses Thema recht differenziert beurteilt und daher bestehen zu der Frage ob es Sinnvoll ist bei einem User Login Ajax zu verwenden immer mehrere Antworten. Ich würde sagen, dass es durchaus sinvoll sein kann Ajax zu verwenden. Wenn man ein paar Dinge, vor allem bei der Sicherheit beachtet, hat die Ajax Variante sogar Sicherheitsvorteile.
Da sind wir auch schon beim Thema: Sicherheit. Der Grund für die kontroverse Beurteilung dieses Themas ist, dass man leicht mit Ajax die schon vorhandene Browser Sicherheit bei Login Abfragen aushebeln kann.
Bei der Authentifizierung via Browser bestehen mehrere Möglichkeiten. Die beiden gängisten Vorgehensweisen sind HTTP Basic Authentication und Form Bases Authentication.
HTTP Basic Authentication
Die erste Möglichkeit bringt der Browser mit und ist die HTTP Basic Authentication. In diesem Fall sendet der Server einen 401 Response (Unauthorized) und der Browser reagiert darauf indem er die User id und das User Passwort abfragt. Diese werden dann base64 enkodiert an den Server zurückgesendet. Sind die Angaben dem Server bekannt und hat der User sich somit mit korrekten Daten eingeloggt wird die eigentlich angefordertet Resource vom Server zurückgegeben. Eine Beschreibung wie man eine solche Authentifizierung mit dem Apache Webserver konfigurieren kann findet sich bei der offiziellen Apache Dokumentation.
(Bild von: Sun J2EE Tutorial – Security)
Form Based Authentication
Da die Basic Authentifizierung die eigentliche Seite erst anzeigt wenn die Daten korrekt eingegeben wurden verwenden viele Seiten eine Form Based Authentication anstatt der Basic Authentication. Diese hat den Vorteil, dass die eigentliche Seite in ihrem Design schon vorliegt. Man bewegt sich also schon im “Kontext” der Seite. Auf der Seite gibt man dann in einem Formular die Login Daten ein, diese werden mit einem Submit an den Server übertragen und dort mit den vorliegenden Daten überprüft. Sind die Daten korrekt wird ein Flag in der Session gesetzt und der User kann auf die ihm nun verfügbaren Seiten zugreifen. Bei einem erfolgreichem Login wird man auf die angeforderte Seite weitergeleitet und bei einem Fehler auf die Fehler Seite. Das ganze muss allerdings Serverseitig selbst implementiert werden wenn die Sprache oder Umgebung nicht schon eine Unterstützung mitbringt. Bei einer J2EE Umgebung kann z. B. der j_security_check genutzt werden.
Bei dieser Variante muss beachtet werden, dass die Logindaten verschlüsselt übertragen werden (https) denn per default werden sie plain Text bei dem Submitten des Formulars übertragen und erst Serverseitig in ein bestimmtes Hash zum überprüfen umgewandelt. Dieser Hashwert muss dann mit dem gespeicherten Hashwert für das korrekte Passwort übereinstimmen. Wer die Passwörter generell plain Text in einer DB abspeichert sollte das schleunigst ändern.
(Bild von: Sun J2EE Tutorial – Security)
Ajax Authentication
Nun aber zu Ajax. Wie kann man die Login Methoden mit Ajax in Verbindung bringen. Grundsätzlich ist die Ajax Variante gleich der Form Bases Authentication. Man hat ein Formular indem die Login Daten eingegeben werden, die Daten werden via XmlHttpRequest (XHR) an den Server übertragen, überprüft und eine entsprechende Antwort zurückgesendet. Nur gibt es generell ein paar Dinge bei dieser Variante zu beachten. Zum einen natürlich die Übertragung der Daten. Wenn nichts geändert wird werden die Daten als plain Text übertragen und sind somit abhörbar. Die erste Lösung ist natürlich wieder HTTPS zu verwenden, welches die Sicherheit wieder von Haus aus mitbringt und man sich um nichts selbst kümmern muss. Da viele Seiten allerdings kein HTTPS verwenden wollen oder können muss eine andere Lösung her.
Die Antwort heisst hier: Das Passwort wird schon im Browser in ein Hash umgewandelt. Das hat den Vorteil, dass die Daten nicht mehr unverschlüsselt, also plain Text, übertragen werden. Jetzt kommt allerdings das Problem, dass die schon verschlüsselten Daten abgehört und wiederverwendet werden können. So kann man die Daten nutzen um sich einzuloggen ohne das Passwort wirklich als lesbaren Text zu kennen. Um dieses Problem zu lösen kommt nun eine neue Variante ins Spiel. Der Server generiert serverseitig ein einmaliges Token mit zufälligen Zeichen (im englischen wird hier oft von einem “Seed” gesprochen). Dieses Token wird anschließend im Browser verwendet um das schon gehashte Passwort noch einmal ein eine neues Hash umzuwandeln. Die Daten werden anschließend an den Server übertragen. Das in der Datenbank gespeicherte Passwort-Hash wird nun auch mit dem Token in ein neues Hash umgewandelt und mit dem vom Browser übertragenen Wert verglichen. Stimmen die beiden Hashwerte überein sind auch die eingegebenen Daten korrekt und der User hat sich authentifiziert.
Wichtig bei dieser Vorgehensweise ist, dass das Token immer nur ein einmaliges Token ist. Bei jeder Anfrage wird das Token neu generiert und ist nur für einen Versuch gültig. So kann ein abgehörtes Hash, was im Browser generiert wurde, nicht noch einaml verwendet werden.
Das schöne bei einer Ajax Authentifizierung ist, dass sie in vielen Fällen sogar sicherer ist als die sonst verwendete Form Based Authentication. Viele Seiten verwenden nämlich kein HTTPS und somit werden die Daten immer unverschlüsselt übertragen. Bei der Ajax Variante werden die Daten schon im Broswer verschlüsselt und man kann das normale HTTP Protokoll verwenden.
Zudem bleibt man im Kontext seiner Seite. Vor allem bei einer falschen Eingabe ist diese Variante sehr angenehm, da man den Fehler direkt angezeigt bekommt ohne eine neue Seite laden zu müssen.
Diese hier beschriebene Variante ist bei ajaxpatterns.org unter dem Pattern Name “Direct Login” beschrieben. Dort wird auch gleich noch ein wenig Code als Beispiel presentiert.
Ein funktionierendes Live Beispiel zu der Direct Login Variante kann bei JamesDam.com gefunden werden (User: user1 / Passwort: pass1). Der Source Code für dieses Beispiel steht auch zu Verfügung und serverseitig wurde php als Sprache verwendet.
Als letzten Punkt noch ein Hinweis auf ein schönes Tutorial von Sanjev Jivan wie man ein Ajax Login mit Acegi realisieren kann. Acegi ist ein Autorisierungs und Authentifizierungs Modul für Spring. Das Problem für ein Ajax Login ist, dass Acegi, wie bei einer Form Based Authentication üblich, immer ein Redirect auf eine neue Seite machen möchte. Das Verhalten muss natürlich unterbunden werden und dazu sind einige Schritte notwendig (Orignal HttpReqeust abfangen – eigens /j_acegi_security_check Servlet Mapping einbinden, eigenen Request weiterleiten und den Redirect abfangen …). Diese Schritte werden in dem Tutorial erläutert.
Fazit
Ich persönlich finde die Ajax Login Variante sehr elegant und würde/werde sie einsetzen. Die beschriebene Ajax Login Vorgehensweise ist sogar noch wesentlich sicherer als viele schon implementierte Form Based Authentications, da viele auf HTTPS verzichten und somit das Passwort unverschlüsselt über die Leitung geht.
Allerdings muss man natürlich beachten, dass nicht jeder Browser das XmlHttpRequest Objekt unterstützt und somit sollte man eine Alternative bereithalten. Man möchte ja nicht schon durch die alleinige Verwendung eines alten Browsers jemanden von seiner Plattform ausschließen ;)
Auch die Wahl des Algorythmuses zum Verschlüsseln des Passwortes im Browser mit JavaScript (z.B. md5) sollte genau begutachtet werden.
Für die Sicherheitsfanatiker unter uns die Anmerkung: der geneigte Webseitenersteller, der eine absolut sichere Login Variante haben möchte, der sollte seinen Usern vorab eine Karte mit Zertifikat, Token und Daten sowie ein passendes Lesegerät verteilen. Das Passwort für die Karte muss natürlich auch übertragen werden… (für weitere Informationen zu diesem Thema hier ein schöner Artikel mit dem Titel “Online-Banking der Zukunft ist sicher vor Phishing” – pdf Format)



