it-swarm.com.de

Erstellen einer API für mobile Anwendungen - Authentifizierung und Autorisierung

Überblick

Ich möchte eine (REST-) API für meine Anwendung erstellen. Der ursprüngliche/primäre Zweck ist der Verbrauch durch mobile Apps (iPhone, Android, Symbian usw.). Ich habe verschiedene Mechanismen für die Authentifizierung und Autorisierung von webbasierten APIs untersucht (indem ich andere Implementierungen studiert habe). Ich habe die meisten grundlegenden Konzepte im Kopf, suche aber in einigen Bereichen immer noch nach Anleitungen. Das Letzte, was ich tun möchte, ist, das Rad neu zu erfinden, aber ich finde keine Standardlösungen, die meinen Kriterien entsprechen. Außerdem möchte ich, dass die API für alle Plattformen/Anwendungen, die sie verwenden, gleich ist.

oAuth

Ich werde meinen Einwand gegen oAuth=) zurückweisen, da ich weiß, dass dies wahrscheinlich die erste angebotene Lösung sein wird. Für mobile Anwendungen (oder genauer gesagt Nicht-Web-Anwendungen) scheint dies einfach falsch zu sein Um die Anwendung zu verlassen (um zu einem Webbrowser zu wechseln), um sich zu authentifizieren, gibt es keine Möglichkeit für den Browser, den Rückruf an die Anwendung (insbesondere plattformübergreifend) zurückzugeben (ich kenne ein paar) von Apps, die das tun, aber es fühlt sich einfach falsch an und gibt eine Pause in der Anwendungs-UX.

Bedarf

  1. Der Benutzer gibt den Benutzernamen/das Passwort in die Anwendung ein.
  2. Jeder API-Aufruf wird von der aufrufenden Anwendung identifiziert.
  3. Der Overhead wird auf ein Minimum reduziert und der Authentifizierungsaspekt ist für Entwickler intuitiv.
  4. Der Mechanismus ist sowohl für den Endbenutzer (seine Anmeldeinformationen sind nicht verfügbar) als auch für den Entwickler (seine Anmeldeinformationen für die Anwendung sind nicht verfügbar) sicher.
  5. Benötigen Sie nach Möglichkeit kein https (auf keinen Fall eine harte Anforderung).

Meine aktuellen Gedanken zur Umsetzung

Ein externer Entwickler fordert ein API-Konto an. Sie erhalten einen Apikey und Apisecret. Für jede Anforderung sind mindestens drei Parameter erforderlich.

  • apikey - wird dem Entwickler bei der Registrierung ausgehändigt
  • timestamp - Doppelt sich als eindeutige Kennung für jede Nachricht für einen bestimmten Apikey
  • hash - ein Hash des Zeitstempels + des Apisecret

Der Apikey ist erforderlich, um die Anwendung zu identifizieren, die die Anforderung ausgibt. Der Zeitstempel verhält sich ähnlich wie oauth_nonce und vermeidet/mildert Wiederholungsangriffe. Der Hash stellt sicher, dass die Anfrage tatsächlich vom Eigentümer des angegebenen Apikeys ausgegeben wurde.

Bei authentifizierten Anfragen (die im Auftrag eines Benutzers ausgeführt werden) bin ich immer noch unentschlossen, ob ich eine access_token-Route oder eine Kombination aus Benutzername und Passwort-Hash verwenden möchte. In jedem Fall ist irgendwann eine Kombination aus Benutzername und Passwort erforderlich. Wenn dies der Fall ist, wird ein Hash aus mehreren Informationen (apikey, apisecret, timestamp) und dem Kennwort verwendet. Ich würde mich über Feedback zu diesem Aspekt freuen. Zu Ihrer Information, sie müssten das Passwort zuerst hashen, da ich die Passwörter nicht ohne Hashing in meinem System speichere.

Fazit

Zu Ihrer Information, dies ist keine Aufforderung zum Erstellen/Strukturieren der API im Allgemeinen, sondern nur zum Behandeln der Authentifizierung und Autorisierung ausschließlich innerhalb einer Anwendung.

Zufällige Gedanken/Bonusfragen

Wie können Sie bei APIs, für die nur ein Apikey als Teil der Anforderung erforderlich ist, verhindern, dass ein anderer Benutzer als der Apikey-Besitzer den Apikey sehen kann (da er im Klartext gesendet wurde), und übermäßige Anforderungen stellen, um ihn über Nutzungsbeschränkungen hinauszuschieben? Vielleicht habe ich es gerade überlegt, aber sollte es nicht etwas geben, um zu bestätigen, dass eine Anfrage an den apikey-Besitzer verifiziert wurde? In meinem Fall war das der Zweck des Apisecret, es wird niemals ohne Hash gezeigt/übertragen.

Apropos Hashes, was ist mit md5 vs hmac-sha1? Ist es wirklich wichtig, wenn alle Werte mit ausreichend langen Daten (dh apisecret) gehasht werden?

Ich hatte zuvor darüber nachgedacht, meinem Benutzer-Passwort-Hash einen Salt pro Benutzer/Zeile hinzuzufügen. Wenn ich das tun würde, wie könnte die Anwendung in der Lage sein, einen passenden Hash zu erstellen, ohne das verwendete Salz zu kennen?

185
jsuggs

Die Art und Weise, wie ich daran denke, den Login-Teil davon in meinen Projekten zu machen, ist:

  1. vor der Anmeldung fordert der Benutzer einen login_token vom Server an. Diese werden auf Anfrage auf dem Server generiert und gespeichert und haben wahrscheinlich eine begrenzte Lebensdauer.

  2. um sich anzumelden, berechnet die Anwendung den Hash des Benutzerpassworts und hasht das Passwort mit login_token, um einen Wert zu erhalten. Anschließend geben sie sowohl den login_token als auch den kombinierten Hash zurück.

  3. Der Server überprüft, ob es sich bei login_token Um eines handelt, das er generiert hat, und entfernt es aus seiner Liste der gültigen login_token. Der Server kombiniert dann seinen gespeicherten Hash des Benutzerpassworts mit dem login_token Und stellt sicher, dass er mit dem übermittelten kombinierten Token übereinstimmt. Wenn es passt, haben Sie Ihren Benutzer authentifiziert.

Dies hat den Vorteil, dass Sie das Kennwort des Benutzers niemals auf dem Server speichern, das Kennwort niemals im Klartext übergeben wird, der Kennwort-Hash nur im Klartext bei der Kontoerstellung übergeben wird (obwohl dies möglicherweise umgangen wird), und dies sollte der Fall sein Vor Wiederholungsangriffen geschützt, da login_token bei Verwendung aus der Datenbank entfernt wird.

43

Das sind eine ganze Reihe von Fragen in einer, ich glaube, einige Leute haben es nicht geschafft, bis zum Ende zu lesen :)

Meine Erfahrung mit der Authentifizierung von Webdiensten ist, dass die Leute sie normalerweise überentwickeln, und die Probleme sind nur die gleichen, wie sie auf einer Webseite auftreten würden. Mögliche sehr einfache Optionen wären https für den Anmeldeschritt, die Rückgabe eines Tokens und dessen Einbeziehung in zukünftige Anforderungen. Sie können auch die HTTP-Basisauthentifizierung verwenden und nur Daten im Header übergeben. Um zusätzliche Sicherheit zu gewährleisten, drehen Sie die Token häufig, lassen Sie sie ablaufen, prüfen Sie, ob die Anforderungen vom selben IP-Block stammen (dies kann jedoch zu Problemen führen, wenn sich mobile Benutzer zwischen Zellen bewegen), kombinieren Sie sie mit einem API-Schlüssel oder ähnlichem. Alternativ können Sie den Schritt "Request Key" von oauth (jemand hat dies bereits in einer früheren Antwort vorgeschlagen und es ist eine gute Idee) ausführen, bevor Sie den Benutzer authentifizieren, und diesen als erforderlichen Schlüssel zum Generieren des Zugangstoken.

Eine Alternative, die ich noch nicht benutzt habe, von der ich aber als gerätefreundliche Alternative zu oAuth gehört habe, ist xAuth Wenn du es benutzt, würde es mich sehr interessieren, was deine Eindrücke sind.

Beim Hashing ist sha1 etwas besser, aber lassen Sie sich nicht aufregen - was auch immer die Geräte einfach (und in Bezug auf die Leistung schnell) implementieren können, ist wahrscheinlich in Ordnung.

Hoffe das hilft, viel Glück :)

13
Lorna Mitchell

Twitter hat das Problem mit externen Anwendungen in oAuth durch Unterstützung einer Variante, die sie xAuth nennen, behoben. Leider gibt es bereits eine Vielzahl anderer Schemata mit diesem Namen, sodass das Sortieren verwirrend sein kann aus.

Das Protokoll is oAuth, außer dass es die Anforderungs-Token-Phase überspringt und einfach sofort nach Erhalt eines Benutzernamens und Passworts ein Zugriffstoken-Paar ausgibt. (Ab hier Schritt E .) Diese Initiale Anfrage und Antwort müssen gesichert sein - Es sendet den Benutzernamen und das Passwort im Klartext und erhält das Zugriffstoken und das geheime Token zurück. Nachdem das Zugriffstokenpaar konfiguriert wurde, spielt es für den Rest der Sitzung keine Rolle, ob der ursprüngliche Tokenaustausch über das oAuth= Modell oder das xAuth-Modell erfolgte Vorteil, dass Sie die vorhandene oAuth Infrastruktur nutzen und für mobile/Web/Desktop-Anwendungen nahezu dieselbe Implementierung haben. Der Hauptnachteil besteht darin, dass der Anwendung der Zugriff auf den Benutzernamen und das Kennwort des Clients gewährt wird. Es scheint jedoch so, als ob Ihre Anforderungen diesen Ansatz erfordern.

Auf jeden Fall möchte ich Ihrer Intuition und der einiger anderer Antwortender hier zustimmen: Versuchen Sie nicht, etwas Neues von Grund auf neu zu bauen. Sicherheitsprotokolle können einfach zu starten sein, sind jedoch immer schwierig zu erstellen. Je komplizierter sie sind, desto unwahrscheinlicher ist es, dass Entwickler von Drittanbietern sie implementieren können. Ihr hypothetisches Protokoll ist sehr ähnlich zu o (x) Auth - api_key/api_secret, nonce, sha1 hashing - aber anstatt in der Lage zu sein, eine der vielen vorhandenen Bibliotheken zu verwenden, müssen Ihre Entwickler ihre eigenen erstellen.

9
lantius

Was Sie also suchen, ist eine Art serverseitiger Authentifizierungsmechanismus, der die Authentifizierungs- und Autorisierungsaspekte einer mobilen Anwendung behandelt?

Unter der Annahme, dass dies der Fall ist, würde ich folgendermaßen vorgehen (aber nur, weil ich ein Java -Entwickler bin, würde es ein C # -Typ anders machen):

Der RESTful-Authentifizierungs- und Autorisierungsdienst

  1. Dies funktioniert nur über HTTPS, um das Abhören zu verhindern.
  2. Es basiert auf einer Kombination von RESTEasy , Spring Security und CAS (für einmaliges Anmelden) über mehrere Anwendungen hinweg).
  3. Es funktioniert sowohl mit Browsern als auch mit webfähigen Client-Anwendungen
  4. Es wird eine webbasierte Benutzeroberfläche für die Kontoverwaltung geben, über die Benutzer ihre Daten bearbeiten können, und Administratoren (für bestimmte Anwendungen) können die Berechtigungsstufen ändern

Die clientseitige Sicherheitsbibliothek/-anwendung

  1. Erstellen Sie für jede unterstützte Plattform (z. B. Symbian, Android, iOS usw.) eine geeignete Implementierung der Sicherheitsbibliothek in der Muttersprache der Plattform (z. B. Java, ObjectiveC, C usw.).
  2. Die Bibliothek sollte die HTTPS-Anforderungsbildung unter Verwendung der verfügbaren APIs für die angegebene Plattform verwalten (z. B. Java verwendet URLConnection usw.).
  3. Benutzer der allgemeinen Authentifizierungs- und Autorisierungsbibliothek (das ist alles, was es ist) codieren auf einer bestimmten Oberfläche und sind nicht erfreut, wenn sich diese ändert. Stellen Sie daher sicher, dass sie sehr flexibel ist. Befolgen Sie vorhandene Designoptionen wie Spring Security.

Wie gehen Sie vor, wenn der Blick aus 30.000 Fuß vollständig ist? Nun, es ist nicht so schwer, ein Authentifizierungs- und Autorisierungssystem basierend auf den auf der Serverseite aufgeführten Technologien mit einem Browser-Client zu erstellen. In Kombination mit HTTPS stellen die Frameworks einen sicheren Prozess bereit, der auf einem gemeinsam genutzten Token (normalerweise als Cookie dargestellt) basiert, das durch den Authentifizierungsprozess generiert und verwendet wird, wann immer der Benutzer etwas unternehmen möchte. Dieses Token wird vom Client dem Server immer dann präsentiert, wenn eine Anforderung erfolgt.

Im Fall der lokalen mobilen Anwendung scheint es, dass Sie nach einer Lösung suchen, die Folgendes bewirkt:

  1. Die Clientanwendung verfügt über eine definierte Zugriffssteuerungsliste (Access Control List, ACL), die den Laufzeitzugriff auf Methodenaufrufe steuert. Beispielsweise kann ein bestimmter Benutzer eine Auflistung aus einer Methode lesen, aber seine ACL ermöglicht nur den Zugriff auf Objekte, deren Name ein Q enthält, sodass einige Daten in der Auflistung vom Security Interceptor als Quiety abgerufen werden. In Java ist dies unkompliziert. Sie verwenden lediglich die Spring Security-Annotationen für den aufrufenden Code und implementieren einen geeigneten ACL-Antwortprozess. In anderen Sprachen sind Sie auf sich allein gestellt und müssen wahrscheinlich einen Sicherheitscode auf der Hauptplatine bereitstellen, der Ihre Sicherheitsbibliothek aufruft. Wenn die Sprache AOP (Aspect Oriented Programming) unterstützt, verwenden Sie sie in dieser Situation in vollem Umfang.
  2. Die Sicherheitsbibliothek speichert die vollständige Liste der Berechtigungen in ihrem privaten Speicher für die aktuelle Anwendung, damit sie nicht verbunden bleiben muss. Abhängig von der Länge der Anmeldesitzung kann dies ein einmaliger Vorgang sein, der niemals wiederholt wird.

Was auch immer Sie tun , versuchen Sie nicht, Ihr eigenes Sicherheitsprotokoll zu erfinden , oder verwenden Sie Sicherheit durch Unbekanntheit. Sie werden niemals in der Lage sein, einen besseren Algorithmus dafür zu schreiben als die derzeit verfügbaren und kostenlosen. Außerdem vertrauen die Leute bekannten Algorithmen. Wenn Sie also sagen, dass Ihre Sicherheitsbibliothek Autorisierung und Authentifizierung für lokale mobile Anwendungen unter Verwendung einer Kombination aus SSL-, HTTPS-, SpringSecurity- und AES-verschlüsselten Token bereitstellt, sind Sie auf dem Markt sofort glaubwürdig.

Ich hoffe, dies hilft und wünsche Ihnen viel Glück bei Ihrem Vorhaben. Wenn Sie weitere Informationen wünschen, lassen Sie es mich wissen. Ich habe einige Webanwendungen geschrieben, die auf Spring Security, ACLs und dergleichen basieren.

8
Gary Rowe

Super spät zur Party, aber ich wollte ein paar zusätzliche Punkte einbringen, die für alle in Betracht gezogen werden sollten, die sich für diese Ausgabe interessieren. Ich arbeite für ein Unternehmen, das Sicherheitslösungen für mobile APIs anbietet ( approxov ), sodass dieser gesamte Bereich definitiv für meine Interessen relevant ist.

Das Wichtigste, was Sie beim Versuch, eine mobile API zu sichern, berücksichtigen müssen, ist, wie viel es Ihnen wert ist. Die richtige Lösung für eine Bank unterscheidet sich von der richtigen Lösung für jemanden, der Dinge nur zum Spaß macht.

In der vorgeschlagenen Lösung erwähnen Sie, dass mindestens drei Parameter erforderlich sind:

  • apikey - wird dem Entwickler bei der Registrierung ausgehändigt
  • timestamp - Doppelt sich als eindeutige Kennung für jede Nachricht für einen bestimmten Apikey
  • hash - ein Hash des Zeitstempels + des Apisecret

Dies hat zur Folge, dass für einige API-Aufrufe kein Benutzername/Kennwort erforderlich ist. Dies kann für Anwendungen nützlich sein, bei denen Sie keine Anmeldung erzwingen möchten (z. B. Surfen in Online-Shops).

Dies ist ein etwas anderes Problem als das der Benutzerauthentifizierung und ähnelt eher der Authentifizierung oder Bestätigung der Software. Es gibt keinen Benutzer, Sie möchten jedoch sicherstellen, dass kein böswilliger Zugriff auf Ihre API besteht. Sie verwenden also Ihr API-Geheimnis, um den Datenverkehr zu signieren und den Code, der auf die API zugreift, als echt zu identifizieren. Das potenzielle Problem bei dieser Lösung ist, dass Sie das Geheimnis in jeder Version der App preisgeben müssen. Wenn jemand das Geheimnis herausholen kann, kann er Ihre API verwenden und sich als Ihre Software ausgeben, aber tun, was er will.

Um dieser Bedrohung entgegenzuwirken, können Sie eine Reihe von Maßnahmen ergreifen, je nachdem, wie wertvoll die Daten sind.Verschleierungist ein einfacher Weg, um die Entschlüsselung des Geheimnisses zu erschweren. Es gibt Tools, die das für Sie erledigen, mehr noch für Android, aber Sie müssen immer noch Code haben, der Ihren Hash generiert, und ein ausreichend erfahrener Benutzer kann immer nur die Funktion aufrufen, die das Hashing direkt durchführt.

Eine andere Möglichkeit, die übermäßige Verwendung einer API, für die keine Anmeldung erforderlich ist, zu verhindern, besteht darin,throttleden Datenverkehr zu überwachen und möglicherweise verdächtige IP-Adressen zu identifizieren und zu blockieren. Der Umfang der Bemühungen, die Sie unternehmen möchten, hängt weitgehend davon ab, wie wertvoll Ihre Daten sind.

Darüber hinaus können Sie leicht in die Domäne meines Tagesberufs einsteigen. Jedenfalls ist es ein weiterer Aspekt bei der Sicherung von APIs, den ich für wichtig halte und den ich melden wollte.

5
ThePragmatist