it-swarm.com.de

REST API Authorization & Authentication (Web + Mobile)

Ich habe über oAuth, Amazon REST API, HTTP Basic/Digest usw. gelesen, kann aber nicht alles in einem Stück zusammenfassen. Dies ist wahrscheinlich die naheliegendste Situation - Erstellen einer API für mobile Anwendungen - Authentifizierung und Autorisierung

Ich möchte einen API-zentrierten Website-Service erstellen. Also (am Anfang) hätte ich eine API im Zentrum und Website (PHP + MySQL) würde eine Verbindung über cURL, Android und iPhone über ihre Netzwerkschnittstellen. Also 3 Hauptclients - 3 API-Schlüssel. Jeder andere Entwickler kann auch über die API-Schnittstelle entwickeln und erhält einen eigenen API-Schlüssel. API-Aktionen werden basierend auf dem UserLevel-Status akzeptiert/abgelehnt. Wenn ich ein Administrator bin, kann ich alles löschen usw., alle anderen können nur ihre lokalen (Konto-) Daten bearbeiten.

Erstens Autorisierung - sollte ich oAuth + xAuth oder meine eigene Implementierung verwenden (siehe http://docs.amazonwebservices.com/AmazonCloudFront/latest /DeveloperGuide/RESTAuthentication.html?r=9197 )? Wie ich verstehe, ist auf Amazon Service-Benutzer == API-Benutzer (API-Schlüssel haben. Bei meinem Dienst muss ich Standardbenutzer/Konto (denjenigen, der sich auf der Website registriert hat) und Entwicklerkonten (der seinen API-Schlüssel haben sollte) trennen.

Also müsste ich zuerst den API-Schlüssel autorisieren und dann den Benutzer authentifizieren selbst. Wenn ich das Schema von Amazon verwende, um die API-Schlüssel der Entwickler zu überprüfen (deren App zu autorisieren), welches Schema soll ich für die Benutzerauthentifizierung verwenden?

Ich habe gelesen, wie ich ein Token über api.example.org/auth Erhalten habe, nachdem ich (über [~ # ~] https [~ # ~], HTTP Basic) meinen Benutzernamen und mein Passwort veröffentlicht und dann weitergeleitet habe jede folgende Anfrage. Wie verwalte ich Tokens, wenn ich gleichzeitig auf Android und einer Website angemeldet bin? Was ist mit Man-in-the-Middle-Attacken, wenn ich SSL nur bei der ersten Anfrage (wenn Benutzername und Passwort übertragen werden) und nur bei jedem anderen HTTP verwende? Ist das nicht ein Problem in diesem Beispiel Kennwort, das einen REST Service schützt?

69
svenkapudija

Wie immer ist der beste Weg, einen Schlüssel zu schützen, ihn nicht zu übertragen.

Das heißt, wir verwenden typischerweise ein Schema, bei dem jeder "API-Schlüssel" zwei Teile aufweist: Eine nicht geheime ID (z. B. 1234) und einen geheimen Schlüssel (z. B. Byte [64]).

  • Wenn Sie einen API-Schlüssel herausgeben, speichern Sie ihn (gesalzen und gehasht) in der Datenbank Ihres Dienstes.
  • Wenn Sie Benutzerkonten vergeben (durch Kennwort geschützt), speichern Sie die Kennwörter (gesalzen und gehasht) in der Datenbank Ihres Dienstes

Wenn nun ein Verbraucher zuerst auf Ihre API zugreift, um eine Verbindung herzustellen, muss er ihn haben

  • Sende einen "Benutzername" -Parameter ("john.doe" nicht geheim)
  • Sende einen "APIkeyID" -Parameter ("1234", nicht geheim)

und gib ihn zurück

  • die Salze aus Ihrer Datenbank (Falls einer der Parameter falsch ist, geben Sie einfach etwas wiederholbares Salz zurück - z. B. sha1 (Benutzername + "notverysecret").
  • Der Zeitstempel des Servers

Der Verbraucher sollte das Salz für die Sitzungsdauer aufbewahren, um die Dinge schnell und reibungslos zu halten, und er sollte den Zeitversatz zwischen Client und Server berechnen und einhalten.

Der Verbraucher sollte nun die gesalzenen Hashes von API-Schlüssel und Passwort berechnen. Auf diese Weise verfügt der Konsument über genau dieselben Hashes für Kennwort und API-Schlüssel wie in Ihrer Datenbank, ohne dass dabei Geheimnisse verloren gehen.

Wenn nun ein Verbraucher nachfolgend auf Ihre API zugreift, um echte Arbeit zu leisten, lassen Sie ihn

  • Sende einen "Benutzername" -Parameter ("john.doe" nicht geheim)
  • Sende einen "APIkeyID" -Parameter ("1234", nicht geheim)
  • Sende einen "RequestSalt" -Parameter (Byte [64], zufällig, nicht geheim)
  • Senden eines "RequestTimestamp" -Parameters (berechnet aus Client-Zeit und bekanntem Offset)
  • Sende einen "RequestToken" -Parameter (Hash (Passworthash + Request_Salt + Request_Timestamp + Apikeyhash))

Der Server sollte Zeitstempel nicht länger als 2 Sekunden in der Vergangenheit akzeptieren, um dies vor einem Wiederholungsangriff zu schützen.

Der Server kann nun denselben Hash (Passworthash + Request_Salt + Request_Timestamp + Apikeyhash) wie der Client berechnen

  • der Client kennt den API-Schlüssel,
  • der Kunde kennt das richtige Passwort
123
Eugen Rieck