Was glauben die Leute beim Erstellen von Anwendungen im SPA-Stil mit Frameworks wie Angular, Ember, React usw. als Best Practices für die Authentifizierung und das Sitzungsmanagement? Ich kann mir ein paar Möglichkeiten vorstellen, wie ich das Problem angehen könnte.
Behandeln Sie es nicht anders als die Authentifizierung mit einer normalen Webanwendung, vorausgesetzt, die API und die Benutzeroberfläche haben dieselbe Ursprungsdomäne.
Dies würde wahrscheinlich ein Sitzungscookie, einen serverseitigen Sitzungsspeicher und wahrscheinlich einen Sitzungs-API-Endpunkt beinhalten, auf den die authentifizierte Web-Benutzeroberfläche zugreifen kann, um aktuelle Benutzerinformationen abzurufen, die bei der Personalisierung helfen oder möglicherweise sogar Rollen / Fähigkeiten auf der Clientseite bestimmen. Der Server würde natürlich weiterhin Regeln zum Schutz des Zugriffs auf Daten durchsetzen. Die Benutzeroberfläche würde diese Informationen nur verwenden, um die Erfahrung anzupassen.
Behandeln Sie es wie einen Drittanbieter-Client, der eine öffentliche API verwendet, und authentifizieren Sie sich mit einem Token-System, das OAuth ähnelt. Dieser Token-Mechanismus wird von der Client-Benutzeroberfläche verwendet, um jede einzelne Anforderung an die Server-API zu authentifizieren.
Ich bin hier nicht wirklich ein Experte, aber # 1 scheint für die überwiegende Mehrheit der Fälle völlig ausreichend zu sein, aber ich würde wirklich gerne mehr erfahrene Meinungen hören.
quelle
Antworten:
Diese Frage wurde hier in etwas anderer Form ausführlich behandelt:
RESTful Authentifizierung
Dies spricht es jedoch von der Serverseite an. Schauen wir uns das von der Client-Seite aus an. Bevor wir das tun, gibt es jedoch einen wichtigen Auftakt:
Javascript Crypto ist hoffnungslos
Matasanos Artikel dazu ist berühmt, aber die darin enthaltenen Lektionen sind ziemlich wichtig:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
Zusammenfassen:
<script> function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
Und um eine eigene Folgerung hinzuzufügen:
Dies macht viele RESTful-Authentifizierungsschemata unmöglich oder albern, wenn Sie beabsichtigen, einen JavaScript-Client zu verwenden. Lass uns nachsehen!
HTTP Basic Auth
In erster Linie HTTP Basic Auth. Das einfachste Schema: Geben Sie bei jeder Anfrage einfach einen Namen und ein Passwort ein.
Dies erfordert natürlich unbedingt SSL, da Sie bei jeder Anfrage einen Base64 (reversibel) -codierten Namen und ein Kennwort übergeben. Jeder, der in der Leitung zuhört, kann den Benutzernamen und das Passwort trivial extrahieren. Die meisten Argumente für "Basic Auth is unsicher" stammen von einem Ort mit "Basic Auth over HTTP", was eine schreckliche Idee ist.
Der Browser bietet integrierte HTTP Basic Auth-Unterstützung, ist aber hässlich und sollte wahrscheinlich nicht für Ihre App verwendet werden. Die Alternative besteht jedoch darin, Benutzername und Passwort in JavaScript zu speichern.
Dies ist die RESTful-Lösung. Der Server benötigt keinerlei Kenntnis des Status und authentifiziert jede einzelne Interaktion mit dem Benutzer. Einige REST-Enthusiasten (meistens Strohmänner) bestehen darauf, dass die Aufrechterhaltung eines Zustands Häresie ist und beim Aufschäumen des Mundes schäumt, wenn Sie an eine andere Authentifizierungsmethode denken. Diese Art der Einhaltung von Standards bietet theoretische Vorteile - sie wird von Apache sofort unterstützt - Sie können Ihre Objekte als Dateien in Ordnern speichern, die durch .htaccess-Dateien geschützt sind, wenn Ihr Herz dies wünscht!
Das Problem ? Sie speichern auf der Clientseite einen Benutzernamen und ein Kennwort zwischen. Dies gibt evil.ru einen besseren Überblick - selbst die grundlegendsten XSS-Schwachstellen können dazu führen, dass der Client seinen Benutzernamen und sein Kennwort auf einen bösen Server überträgt. Sie könnten versuchen, dieses Risiko durch Hashing und Salting des Passworts zu verringern, aber denken Sie daran: JavaScript Crypto ist hoffnungslos . Sie könnten dieses Risiko verringern, indem Sie es der Basisauthentifizierungsunterstützung des Browsers überlassen, aber wie bereits erwähnt hässlich wie Sünde.
HTTP Digest Auth
Ist eine Digest-Authentifizierung mit jQuery möglich?
Eine "sicherere" Authentifizierung, dies ist eine Anfrage / Antwort-Hash-Herausforderung. Außer JavaScript Crypto ist hoffnungslos , funktioniert also nur über SSL und Sie müssen den Benutzernamen und das Kennwort auf der Clientseite zwischenspeichern, was es komplizierter als HTTP Basic Auth macht, aber nicht sicherer .
Abfrageauthentifizierung mit zusätzlichen Signaturparametern.
Eine weitere "sicherere" Authentifizierung, bei der Sie Ihre Parameter mit Nonce- und Timing-Daten verschlüsseln (zum Schutz vor Wiederholungs- und Timing-Angriffen) und die senden. Eines der besten Beispiele hierfür ist das OAuth 1.0-Protokoll, das meines Wissens eine ziemlich einfache Möglichkeit darstellt, die Authentifizierung auf einem REST-Server zu implementieren.
http://tools.ietf.org/html/rfc5849
Oh, aber es gibt keine OAuth 1.0-Clients für JavaScript. Warum?
JavaScript Crypto ist hoffnungslos , denken Sie daran. JavaScript kann ohne SSL nicht an OAuth 1.0 teilnehmen, und Sie müssen den Benutzernamen und das Kennwort des Clients weiterhin lokal speichern. Dies entspricht der Kategorie Digest Auth. Es ist komplizierter als HTTP Basic Auth, aber nicht sicherer .
Zeichen
Der Benutzer sendet einen Benutzernamen und ein Kennwort und erhält im Gegenzug ein Token, mit dem Anforderungen authentifiziert werden können.
Dies ist geringfügig sicherer als HTTP Basic Auth, da Sie die vertraulichen Daten verwerfen können, sobald die Transaktion zwischen Benutzername und Kennwort abgeschlossen ist. Es ist auch weniger RESTful, da Token "Status" darstellen und die Serverimplementierung komplizierter machen.
SSL immer noch
Das Problem ist jedoch, dass Sie immer noch diesen anfänglichen Benutzernamen und das Passwort senden müssen, um ein Token zu erhalten. Vertrauliche Informationen berühren immer noch Ihr kompromittierbares JavaScript.
Um die Anmeldeinformationen Ihres Benutzers zu schützen, müssen Sie Angreifer weiterhin von Ihrem JavaScript fernhalten und weiterhin einen Benutzernamen und ein Kennwort über das Netzwerk senden. SSL erforderlich.
Token-Ablauf
Es ist üblich, Token-Richtlinien wie "Hey, wenn dieses Token zu lange existiert, verwerfen Sie es und lassen Sie den Benutzer erneut authentifizieren." Durchzusetzen. oder "Ich bin mir ziemlich sicher, dass die einzige IP-Adresse, die dieses Token verwenden darf,
XXX.XXX.XXX.XXX
" ist. Viele dieser Richtlinien sind ziemlich gute Ideen.Feuersheeping
Die Verwendung eines Tokens ohne SSL ist jedoch weiterhin anfällig für einen Angriff namens "Sidejacking": http://codebutler.github.io/firesheep/
Der Angreifer erhält die Anmeldeinformationen Ihres Benutzers nicht, kann sich jedoch als Benutzer ausgeben, was ziemlich schlecht sein kann.
tl; dr: Das Senden unverschlüsselter Token über das Kabel bedeutet, dass Angreifer diese Token leicht schnappen und sich als Benutzer ausgeben können. FireSheep ist ein Programm, das dies sehr einfach macht.
Eine separate, sicherere Zone
Je größer die Anwendung ist, die Sie ausführen, desto schwieriger ist es sicherzustellen, dass sie keinen Code einfügen können, der die Verarbeitung vertraulicher Daten ändert. Vertrauen Sie Ihrem CDN absolut? Ihre Werbetreibenden? Ihre eigene Codebasis?
Häufig für Kreditkartendaten und seltener für Benutzername und Kennwort - Einige Implementierer speichern die Eingabe sensibler Daten auf einer vom Rest ihrer Anwendung getrennten Seite. Diese Seite kann streng kontrolliert und so gut wie möglich gesperrt werden, vorzugsweise auf einer ist schwierig, Benutzer mit Phishing.
Cookie (bedeutet nur Token)
Es ist möglich (und üblich), das Authentifizierungstoken in ein Cookie einzufügen. Dies ändert keine der Eigenschaften von auth mit dem Token, es ist eher eine bequeme Sache. Alle vorherigen Argumente gelten weiterhin.
Sitzung (bedeutet immer noch nur Token)
Session Auth ist nur eine Token-Authentifizierung, aber mit ein paar Unterschieden, die es etwas anders erscheinen lassen:
Abgesehen davon unterscheidet es sich jedoch nicht wirklich von Token Auth.
Dies geht noch weiter von einer RESTful-Implementierung entfernt - mit Statusobjekten gehen Sie auf einem Stateful-Server immer weiter auf dem Weg des einfachen alten RPC.
OAuth 2.0
OAuth 2.0 befasst sich mit dem Problem: "Wie gewährt Software A Software B Zugriff auf die Daten von Benutzer X, ohne dass Software B Zugriff auf die Anmeldeinformationen von Benutzer X hat?"
Die Implementierung ist nur eine Standardmethode für einen Benutzer, um ein Token zu erhalten, und dann für einen Drittanbieter, der sagt: "Ja, dieser Benutzer und dieses Token stimmen überein, und Sie können jetzt einige ihrer Daten von uns erhalten."
Grundsätzlich ist OAuth 2.0 jedoch nur ein Token-Protokoll. Es weist die gleichen Eigenschaften wie andere Token-Protokolle auf - Sie benötigen immer noch SSL, um diese Token zu schützen - es ändert lediglich die Art und Weise, wie diese Token generiert werden.
OAuth 2.0 kann Ihnen auf zwei Arten helfen:
Aber wenn es darauf ankommt, benutzt du nur ... Token.
Zurück zu Ihrer Frage
Die Frage, die Sie stellen, lautet also: "Soll ich mein Token in einem Cookie speichern und die automatische Sitzungsverwaltung meiner Umgebung für die Details sorgen, oder sollte ich mein Token in Javascript speichern und diese Details selbst verarbeiten?"
Und die Antwort lautet: Tu, was dich glücklich macht .
Die Sache mit der automatischen Sitzungsverwaltung ist jedoch, dass hinter den Kulissen für Sie viel Magie passiert. Oft ist es besser, die Kontrolle über diese Details selbst zu haben.
Ich bin 21, also ist SSL ja
Die andere Antwort lautet: Verwenden Sie https für alles, oder Räuber stehlen die Passwörter und Token Ihrer Benutzer.
quelle
It's also less RESTful, as tokens constitute "state and make the server implementation more complicated."
(1) Für REST muss der Server zustandslos sein. Ein clientseitig gespeichertes Token repräsentiert den Status für den Server in keiner sinnvollen Weise. (2) Etwas komplizierterer serverseitiger Code hat nichts mit RESTfulness zu tun.lol_nope_send_it_to_me_instead
Ich habe den Namen dieser Funktion geliebt: DSie können die Sicherheit im Authentifizierungsprozess mithilfe von JWT (JSON Web Tokens) und SSL / HTTPS erhöhen .
Die Basisauthentifizierung / Sitzungs-ID kann gestohlen werden über:
Mit JWT verschlüsseln Sie die Authentifizierungsdetails des Benutzers, speichern sie im Client und senden sie zusammen mit jeder Anforderung an die API, wo der Server / die API das Token validiert.
Es kann nicht ohne den privaten Schlüssel (den der Server / die API geheim speichert) entschlüsselt / gelesen werden. Update lesen .Der neue (sicherere) Fluss wäre:
Anmeldung
Jede Anfrage an API
Aktualisiert am 30.07.15:
JWT-Nutzdaten / -Ansprüche können tatsächlich ohne den privaten Schlüssel (geheim) gelesen werden, und es ist nicht sicher, ihn in localStorage zu speichern. Es tut mir leid wegen dieser falschen Aussagen. Sie scheinen jedoch an einem JWE-Standard (JSON Web Encryption) zu arbeiten .
Ich habe dies implementiert, indem ich Ansprüche (userID, exp) in einem JWT gespeichert, mit einem privaten Schlüssel (geheim) signiert, den die API / das Backend nur kennt, und als sicheres HttpOnly-Cookie auf dem Client gespeichert habe. Auf diese Weise kann es nicht über XSS gelesen und nicht manipuliert werden, da sonst die JWT die Signaturüberprüfung nicht besteht. Durch die Verwendung eines sicheren HttpOnly- Cookies stellen Sie außerdem sicher, dass das Cookie nur über HTTP-Anforderungen (für das Skript nicht zugänglich) und nur über eine sichere Verbindung (HTTPS) gesendet wird.
Aktualisiert am 17.07.16:
JWTs sind von Natur aus staatenlos. Das heißt, sie machen sich selbst ungültig / verfallen. Indem Sie die Sitzungs-ID zu den Ansprüchen des Tokens hinzufügen, machen Sie es statusbehaftet, da seine Gültigkeit jetzt nicht nur von der Signaturüberprüfung und dem Ablaufdatum abhängt, sondern auch vom Sitzungsstatus auf dem Server. Der Vorteil ist jedoch, dass Sie Token / Sitzungen leicht ungültig machen können, was Sie mit zustandslosen JWTs zuvor nicht konnten.
quelle
Ich würde mich für das zweite entscheiden, das Tokensystem.
Wussten Sie schon über Ember-Auth oder Ember-Simple-Auth ? Beide verwenden das tokenbasierte System wie die Ember-Simple-Auth-Zustände:
Sie verfügen über Sitzungsverwaltung und lassen sich auch problemlos in vorhandene Projekte integrieren.
Es gibt auch eine Ember App Kit-Beispielversion von ember-simple-auth: Arbeitsbeispiel für ember-app-kit mit ember-simple-auth für die OAuth2-Authentifizierung.
quelle