Authentifizierung, Autorisierung und Sitzungsverwaltung in herkömmlichen Web-Apps und APIs

74

Korrigieren Sie mich, wenn ich falsch liege: In einer herkömmlichen Webanwendung hängt der Browser Sitzungsinformationen automatisch an eine Anforderung an den Server an, damit der Server wissen kann, von wem die Anforderung stammt. Was genau ist eigentlich angehängt?

In einer API-basierten App werden diese Informationen jedoch nicht automatisch gesendet. Wenn ich also eine API entwickle, muss ich selbst überprüfen, ob die Anforderung beispielsweise von einem authentifizierten Benutzer stammt. Wie wird das normalerweise gemacht?

Jiew Meng
quelle
1
Ich hoffe, Sie haben Ihre vorherigen Webanwendungen nicht unter der Annahme entwickelt, dass der Browser die Sitzung korrekt verwaltet.
2
@bor, ich bin mir nicht sicher, ob ich das richtig gemacht habe, aber ich bin mir ziemlich sicher, dass es in Ordnung ist. Früher habe ich PHP verwendet, also habe ich gerade nachgesehen $_SESSION, stimmt das? Bisher fand ich, dass es gut funktioniert. Es scheint, als würden Browser die Sitzung / Cookies verarbeiten?
Jiew Meng

Antworten:

121

Das HTTP-Protokoll ist vom Status her zustandslos. Jede Anforderung wird separat ausgeführt und in einem separaten Kontext ausgeführt.

Die Idee hinter dem Sitzungsmanagement besteht darin, Anforderungen von demselben Client in denselben Kontext zu stellen. Dazu wird vom Server eine Kennung ausgegeben und an den Client gesendet. Der Client speichert diese Kennung und sendet sie in nachfolgenden Anforderungen erneut, damit der Server sie identifizieren kann.

Kekse

In einem typischen Browser-Server-Fall; Der Browser verwaltet für jede Domain eine Liste von Schlüssel / Wert-Paaren, die als Cookies bezeichnet werden:

  • Cookies können vom Server (erstellt / geändert / gelöscht) mithilfe des Set-CookieHTTP-Antwortheaders verwaltet werden.
  • Auf Cookies kann der Server zugreifen (lesen), indem er den CookieHTTP-Anforderungsheader analysiert .

Web-zielgerichtete Programmiersprachen / Frameworks bieten Funktionen für den Umgang mit Cookies auf einer höheren Ebene, z. B. PHP bietet setcookie/ $_COOKIEzum Schreiben / Lesen von Cookies.

Sitzungen

Zurück zu den Sitzungen In einem typischen Browser-Server-Fall (wieder) nutzt die serverseitige Sitzungsverwaltung die clientseitige Cookie-Verwaltung. Das Sitzungsmanagement von PHP setzt ein Sitzungs-ID-Cookie und verwendet es, um nachfolgende Anforderungen zu identifizieren.

Webanwendungs-API?

Nun zurück zu Ihrer Frage; Da Sie für das Entwerfen und Dokumentieren der API verantwortlich sind, ist die Implementierung Ihre Entscheidung. Sie müssen im Grunde

  1. Geben Sie dem Client eine Kennung, sei es über einen Set-CookieHTTP-Antwortheader, innerhalb des Antwortkörpers (XML / JSON-Authentifizierungsantwort).
  2. über einen Mechanismus zur Aufrechterhaltung der Kennung / Client-Zuordnung verfügen. Beispiel: Eine Datenbanktabelle, die dem 00112233445566778899aabbccddeeffClient / Benutzer # eine Kennung zuordnet 1337.
  3. Lassen Sie den Client die ihm bei allen nachfolgenden Anforderungen unter (1.) gesendete Kennung erneut senden, sei es in einem HTTP- CookieAnforderungsheader, einem ?sid=00112233445566778899aabbccddeeffParameter (*).
  4. Suchen Sie die empfangene Kennung mithilfe des Mechanismus unter (2.), überprüfen Sie, ob eine gültige Authentifizierung vorliegt, und sind Sie berechtigt, die angeforderte Operation auszuführen, und fahren Sie dann mit der Operation im Namen des autorisierten Benutzers fort.

Natürlich können Sie auf der vorhandenen Infrastruktur aufbauen, das Sitzungsmanagement von PHP (das sich um 1./2. Und den Authentifizierungsteil von 4. kümmert) in Ihrer App verwenden und erfordern, dass die clientseitige Implementierung das Cookie-Management durchführt (das würde sich um 3.) kümmern, und dann erledigen Sie den Rest Ihrer App-Logik darauf.


(*) Jeder Ansatz hat Vor- und Nachteile. Beispielsweise ist die Verwendung eines GET-Anforderungsparameters einfacher zu implementieren, kann jedoch Auswirkungen auf die Sicherheit haben, da GET-Anforderungen protokolliert werden. Sie sollten https für kritische (alle?) Anwendungen verwenden.

Aularon
quelle
2
Perfekte Antwort! Danke
Harsh Dattani
Einer der wichtigsten Aspekte des Sitzungsmanagements ist die Sicherheit, um jedem Leser weitere Informationen hinzuzufügen. Dies hat viele Aspekte: Welche Arten von Token müssen verwendet werden, wie würde der Widerruf funktionieren, wie lang und entropisch die Token sind und wie sie vor einer Vielzahl von Angriffen geschützt sind. Wie können wir eine solche Aktivität erkennen, falls Token gestohlen werden (was theoretisch immer möglich ist) (siehe Rotieren von Aktualisierungstoken in RFC 6819)? Da es mir unmöglich ist, alle meine Gedanken in diesem Kommentarbereich zu erklären, können Sie hier mehr über dieses Thema lesen: medium.com/@supertokens.io/ee5245e6bdad
Rishabh Poddar
46

Die Sitzungsverwaltung liegt in der Verantwortung des Servers. Wenn eine Sitzung erstellt wird, wird ein Sitzungstoken generiert und an den Client gesendet (und in einem Cookie gespeichert). Danach sendet der Client bei den nächsten Anforderungen zwischen Client und Server das Token (normalerweise) als HTTP-Cookie. Alle Sitzungsdaten werden auf dem Server gespeichert, der Client speichert nur das Token. Um beispielsweise eine Sitzung in PHP zu starten, müssen Sie nur:

session_start();  // Will create a cookie named PHPSESSID with the session token

Nachdem die Sitzung erstellt wurde, können Sie Daten darauf speichern. Wenn Sie beispielsweise einen Benutzer protokollieren möchten:

// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;

Jetzt können Sie überprüfen, ob ein Benutzer authentifiziert ist oder nicht:

if ($_SESSION['userID'])
    echo 'user is authenticated';
else
    echo 'user isn't authenticated';       

Wenn Sie möchten, können Sie eine Sitzung nur für einen authentifizierten Benutzer erstellen:

if (verifyAccountInformation($user,$pass)){ // Check user credentials
    // Will create a cookie named PHPSESSID with the session token
    session_start();
    $_SESSION['userID'] = 123;
}
Guilherme Torres Castro
quelle
9

Es gibt zahlreiche Möglichkeiten für authentische Benutzer, sowohl für Webanwendungen als auch für APIs. Es gibt einige Standards, oder Sie können Ihre eigene benutzerdefinierte Autorisierung / und / oder Authentifizierung schreiben. Ich möchte auf den Unterschied zwischen Autorisierung und Authentifizierung hinweisen. Zunächst muss die Anwendung den Benutzer (oder API-Client) authentifizieren, von dem die Anforderung stammt. Sobald der Benutzer authentifiziert wurde, muss die Anwendung anhand der Identität des Benutzers bestimmen, welcher authentifizierte Benutzer die Berechtigung zum Ausführen bestimmter Anwendungen hat (Autorisierung). Bei den meisten herkömmlichen Webanwendungen gibt es keine feine Granularität im Sicherheitsmodell. Sobald der Benutzer authentifiziert ist, ist er in den meisten Fällen auch berechtigt, bestimmte Aktionen auszuführen. Diese beiden Konzepte (Authentifizierung und Autorisierung) sollten jedoch zwei verschiedene logische Operationen sein.

Darüber hinaus werden in klassischen Webanwendungen nach der Authentifizierung und Autorisierung des Benutzers (hauptsächlich durch Nachschlagen des Benutzernamen / Passwort-Paares in der Datenbank) Autorisierungs- und Identitätsinformationen in den Sitzungsspeicher geschrieben. Der Sitzungsspeicher muss nicht serverseitig sein, wie die meisten der obigen Antworten vermuten lassen. Er kann auch in Cookies auf der Clientseite gespeichert werden, die in den meisten Fällen verschlüsselt sind. Das PHP CodeIgniter-Framework führt dies beispielsweise standardmäßig aus. Es gibt eine Reihe von Mechanismen zum Schutz von Sitzungen auf der Clientseite, und ich sehe diese Art des Speicherns von Sitzungsdaten nicht weniger sicher als das Speichern der Sitzungs-ID, die dann im Sitzungsspeicher auf der Serverseite nachgeschlagen wird. Außerdem ist das Speichern clientseitig in einer verteilten Umgebung sehr praktisch.

Darüber hinaus muss die Authentifizierung mit einem einfachen Benutzer-Passwort-Paar nicht in jedem Fall über benutzerdefinierten Code erfolgen, der nach übereinstimmenden Benutzerdatensätzen in der Datenbank sucht. Es gibt zum Beispiel ein grundlegendes Authentifizierungsprotokoll oder eine Digest-Authentifizierung . Auf proprietärer Software wie der Windows-Plattform gibt es auch Möglichkeiten zur Authentifizierung von Benutzern über beispielsweise ActiveDirectory

Die Angabe eines Benutzernamen / Passwort-Paares ist nicht nur eine Möglichkeit zur Authentifizierung. Wenn Sie das HTTPS-Protokoll verwenden, können Sie auch die Authentifizierung mithilfe digitaler Zertifikate in Betracht ziehen .

In bestimmten Anwendungsfällen gibt es beim Entwerfen eines Webdienstes, der SOAP als Protokoll verwendet, auch eine WS-Security- Erweiterung für das SOAP-Protokoll.

Nach alledem würde ich sagen, dass Antworten auf die folgende Frage das Entscheidungsverfahren für die Auswahl des Autorisierungs- / Authentifizierungsmechanismus für WebApi eingeben:

1) Was ist die Zielgruppe, ist sie öffentlich verfügbar oder nur für registrierte (zahlende) Mitglieder?
2) Wird es ausgeführt oder * NIX oder MS-Plattform
? 3) Welche Anzahl von Benutzern wird erwartet?
4) Wie viel sensible Daten-API verarbeitet (stärkere oder schwächere Authentifizierungsmechanismen)
5) Gibt es einen SSO-Dienst, den Sie verwenden könnten?

.. und viele mehr.

Hoffe, dass dies die Dinge ein wenig klärt, da es viele Variablen in der Gleichung gibt.

toske
quelle
1

Wenn die API-basierte APP ein Client ist, muss die API die Option haben, die Cookies aus dem Server-Antwortstrom abzurufen / zu lesen und zu speichern. Zum automatischen Anhängen von Cookies beim Vorbereiten des Anforderungsobjekts für denselben Server / dieselbe URL. Wenn es nicht verfügbar ist, kann die Sitzungs-ID nicht abgerufen werden.

Bharath
quelle
1

Sie haben Recht, der Grund, warum die Dinge in einer Standardumgebung "automatisch" sind, ist, dass Cookies der URL-Weitergabe vorgezogen werden, um die Dinge für die Benutzer schön zu halten. Der Browser (Client-Software) verwaltet jedoch das Speichern und Senden des Sitzungscookies zusammen mit jeder Anforderung.

In der API-Welt werden bei einfachen Systemen häufig nur Authentifizierungsdaten mit jeder Anforderung weitergegeben (zumindest in meiner Branche). Kundenautoren zögern normalerweise (wieder meiner Erfahrung nach), die Speicherung und Übertragung von Cookies bei jeder Anfrage und im Allgemeinen mehr als das Nötigste zu implementieren ...

Es gibt viele andere Authentifizierungsmechanismen für HTTP-basierte APIs, HTTP Basic / Digest, um nur einige zu nennen, und natürlich die allgegenwärtige O-Authentifizierung, die speziell für diese Dinge entwickelt wurde, wenn ich mich nicht irre. Es werden keine Cookies gepflegt, Anmeldeinformationen sind Teil jedes Austauschs (ziemlich sicher).

Die andere zu berücksichtigende Sache ist, was Sie mit der Sitzung auf dem Server in einer API tun werden. Die Sitzung auf einer Website bietet Speicherplatz für den aktuellen Benutzer und speichert normalerweise kleine Datenmengen, um die Datenbank von Seite zu Seite zu entlasten. In einem API-Kontext ist dies weniger notwendig, da die Dinge mehr oder weniger zustandslos sind, was im Allgemeinen natürlich der Fall ist. Es kommt wirklich darauf an, was der Dienst tut.

Quickshiftin
quelle
1

Ich würde vorschlagen, dass Sie bei jeder Anfrage eine Art Token senden.

Abhängig vom Server und Dienst kann dies ein JSESSIONID- Parameter in Ihrer GET / POST-Anforderung oder etwas ausgereiftes wie SAML in SOAP über HTTP in Ihrer Webdienstanforderung sein.

iga
quelle