2014-01-20 6 views
12

Ich versuche zu verstehen, welche Möglichkeiten ich habe, um einen Authentifizierungsmechanismus für Anwendungen zu erstellen, die auf einer beliebigen Anzahl von Webservern laufen können. Bis jetzt habe ich nur Erfahrung mit kleinen Websites, die (web-) serverseitige Sitzungen verwenden, um die Aspekte der Authentifizierung zu verwalten. Aber sobald ich weitere Web-Server (oder "Web-Instanzen" in PaaS-Umgebungen hinzufügen möchte), wird dieser Ansatz offensichtlich zu einem Problem; Authentifizierungsstatus, der an bestimmte Computer gebunden ist, ist meines Wissens nicht das, was Sie wollen, wenn Sie den Lastenausgleich verwenden (afaik sticky sessions/Sticky load balancing ist etwas, das vermieden werden sollte). Ich suche nach einer Lösung, die es mir erlaubt, die Anzahl von Webservern/Instanzen dynamisch hoch und runter zu skalieren, ohne sich um den Authentifizierungsmechanismus kümmern zu müssen.Stateless Login/Authentifizierungsmechanismen für skalierbare Webanwendungen?

Ich denke, der einzige Weg, dies zu erreichen, ist Session/Authentifizierungsstatus aus meinen Webservern zu nehmen. Das meinte ich mit "staatenlos". Natürlich muss dieser Zustand irgendwo zwischengespeichert werden, also muss es etwas geben, das nicht staatenlos ist.

Ich könnte einen Datenbankserver verwenden, um alle Authentifizierungssitzungen zu verwalten. Auf den Datenbankserver kann von allen meinen Webservern bei jeder HTTP-Anforderung zugegriffen werden, um nach dem Authentifizierungsstatus von Benutzern zu fragen. Aber da Datenbankserver noch schwieriger zu skalieren sind als Webserver (das wäre meine Annahme, ohne dass ich damit Erfahrung habe), würde ich das Problem einfach von Webservern auf Datenbankserver verlagern. Abgesehen davon denke ich nicht, dass es die beste Lösung in Bezug auf die Leistung wäre.

Anstelle eines Datenbankservers könnte ich vielleicht einen Cache-Server wie Memcached oder Redis verwenden, um die Sitzungen für die Authentifizierung zu verwalten. Ich denke, das würde die Skalierbarkeitsprobleme minimieren, da ein einzelner Cache-Server viele Sitzungen auf eine performante Weise verwalten könnte (oder irre ich mich zu diesem Zeitpunkt?). Aber ich lese manchmal Dinge wie "ein wichtiger Punkt über den Cache ist, dass es sich genau wie ein Cache verhält: die Daten, die Sie gerade gespeichert haben, können einfach verschwinden." Nun, das wäre ein Problem. Ich möchte nicht, dass sich Benutzer alle 2 Stunden anmelden müssen. Meine Frage ist: Warum gehen Daten in einem Cache verloren, wenn der Cache genug Speicher hat? Würden 250 MB Speicher im Cache-Server nicht ausreichen, um über eine Million Sitzungen gleichzeitig zu verwalten, ohne Daten loswerden zu müssen (wenn einfache Schlüssel-Wert-Paare Sitzungs-IDs auf Benutzer-IDs oder umgekehrt)?

Eine dritte Lösung könnte darin bestehen, den Authentifizierungsstatus in Cookies zu speichern, die vom Server signiert wurden und von den Clients nicht manipuliert werden können. Aber wenn ich nicht falsch bin, gibt es keine Möglichkeit für die Serverseite die Abmeldung eines bestimmten Benutzers zu erzwingen ...

Um meine Anforderungen zusammenzufassen:

  • I Web-Server hinter skalieren möchten ein Load-Balancer auf und ab und das auth-System sollte damit umgehen

  • Benutzer sollten
    wie zB angemeldet für mindestens mehrere Tage werden dürfen auf stackoverflow.com

  • Die Server-Seite sollte in der Lage sein, Benutzer abmelden, wenn es ein Grund ist so

Ich habe Interesse an Best Practices zu tun. Ich denke, es gibt eine Menge Websites , die die gleichen Probleme haben und Lösungen dafür gefunden haben.

Antwort

5

This github project ist ein guter Anfang. Die Umsetzung ist im Play! Framework, aber es ist eine gute Erklärung für das, wonach ich glaube. Hilft auch CSRF zu überwinden, die in der App inhärent sein könnte.

Der Server sendet nach der Anmeldung ein auth_token (via https) zurück. Das auth_token wird als Cookie gespeichert (nur so wird es dauerhaft und vom Client aus zugänglich). Wenn eine Anfrage gemacht wird, wird das auth_token als ein HTTP-Header (über JavaScript) platziert, der in den Cookies gespeichert wurde. Dann wird es vom Server-Request-Handler abgezogen und mit jeder Anfrage validiert. Es ist also ein Cookie - aber nicht als Cookie verwendet. Ein "zweimal gebackener" Cookie, wenn du willst :) Die Links erklären mehr im Detail.

Und eine andere Antwort here on stack overflow fand ich eine sehr ähnliche Sache. Eine "Sitzung ohne Sitzung"

Und dann, wenn Sie wirklich in sie owasp.org Besuche graben wollen auf CSRF Prävention, die eine ähnliche Technik unter der Überschrift „General Recommendation: Synchronizer Token Pattern

Die gesamte Kommunikation sollte HTTPS sein erklärt.