Überblick
Ich möchte eine (REST) API für meine Anwendung erstellen. Der ursprüngliche Hauptzweck ist der Verbrauch durch mobile Apps (iPhone, Android, Symbian usw.). Ich habe verschiedene Mechanismen zur Authentifizierung und Autorisierung für webbasierte APIs untersucht (indem ich andere Implementierungen untersucht habe). Ich habe mich mit den meisten grundlegenden Konzepten beschäftigt, suche aber immer noch nach Anleitung in einigen Bereichen. Das Letzte, was ich tun möchte, ist, das Rad neu zu erfinden, aber ich finde keine Standardlösungen, die meinen Kriterien entsprechen (obwohl meine Kriterien falsch sind, können Sie dies auch kritisieren). 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ückwerfen, da ich weiß, dass dies wahrscheinlich die erste angebotene Lösung sein wird. Für mobile Anwendungen (oder insbesondere Nicht-Webanwendungen) scheint es einfach falsch, die Anwendung (um zu einem Webbrowser zu gehen) für die Authentifizierung zu verlassen. Darüber hinaus gibt es (wie mir bekannt ist) keine Möglichkeit für den Browser, den Rückruf an die Anwendung zurückzugeben (insbesondere plattformübergreifend). Ich kenne ein paar Apps, die das tun, aber es fühlt sich einfach falsch an und gibt eine Pause in der Anwendung UX.
Bedarf
- Der Benutzer gibt den Benutzernamen / das Passwort in die Anwendung ein.
- Jeder API-Aufruf wird von der aufrufenden Anwendung identifiziert.
- Der Overhead wird auf ein Minimum reduziert und der Authentifizierungsaspekt ist für Entwickler intuitiv.
- Der Mechanismus ist sowohl für den Endbenutzer (ihre Anmeldeinformationen sind nicht verfügbar) als auch für den Entwickler (ihre Anwendungsanmeldeinformationen sind nicht verfügbar) sicher.
- Wenn möglich, benötigen Sie kein https (keineswegs eine harte Anforderung).
Meine aktuellen Gedanken zur Implementierung
Ein externer Entwickler fordert ein API-Konto an. Sie erhalten eine Apikey und Apisecret. Für jede Anfrage sind mindestens drei Parameter erforderlich.
- apikey - wird dem Entwickler bei der Registrierung gegeben
- Zeitstempel - dient gleichzeitig als eindeutige Kennung für jede Nachricht für eine bestimmte Apikey
- Hash - ein Hash des Zeitstempels + des Apisecret
Der Apikey muss die Anwendung identifizieren, die die Anfrage ausstellt. 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 Apikey gestellt wurde.
Bei authentifizierten Anforderungen (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 Kennwort-Hash verwenden möchte. In jedem Fall ist irgendwann eine Kombination aus Benutzername und Passwort erforderlich. Wenn dies der Fall ist, wird ein Hash mit mehreren Informationen (apikey, apisecret, timestamp) + dem Passwort verwendet. Ich würde gerne Feedback zu diesem Aspekt erhalten. Zu Ihrer Information, sie müssten zuerst das Passwort hashen, da ich die Passwörter nicht ohne Hashing in meinem System speichere.
Fazit
Zu Ihrer Information, dies ist keine Anforderung 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 eine andere Person als der Apikey-Eigentümer den Apikey sehen kann (seitdem im Klartext gesendet), und übermäßige Anforderungen stellen, um sie über die Nutzungsbeschränkungen zu verschieben? Vielleicht denke ich gerade darüber nach, aber sollte es nicht etwas geben, das bestätigt, dass eine Anfrage an den apikey-Besitzer verifiziert wurde? In meinem Fall, das war der Zweck des Apisecret, wird es niemals gezeigt / übertragen, ohne gehasht zu werden.
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 ein Passwort-Hash pro Benutzer / Zeile hinzuzufügen. Wenn ich das tun würde, wie könnte die Anwendung einen passenden Hash erstellen, ohne das verwendete Salz zu kennen?
Antworten:
Die Art und Weise, wie ich darüber nachdenke, den Login-Teil in meinen Projekten durchzuführen, ist:
Vor dem Anmelden fordert der Benutzer eine
login_token
vom Server an. Diese werden auf Anfrage generiert und auf dem Server gespeichert und haben wahrscheinlich eine begrenzte Lebensdauer.login_token
Um sich anzumelden, berechnet die Anwendung den Hash des Benutzerkennworts, hasht dann das Kennwort mit dem , um einen Wert zu erhalten, und gibt dann sowohl denlogin_token
als auch den kombinierten Hash zurück.Der Server überprüft die von
login_token
ihm generierte Datei und entfernt sie aus seiner Liste der gültigenlogin_token
s. Der Server kombiniert dann seinen gespeicherten Hash des Benutzerpassworts mit demlogin_token
und stellt sicher, dass er mit dem übermittelten kombinierten Token übereinstimmt. Wenn es übereinstimmt, haben Sie Ihren Benutzer authentifiziert.Dies hat den Vorteil, dass Sie das Kennwort des Benutzers niemals auf dem Server speichern, das Kennwort niemals im Clear übergeben wird, der Kennwort-Hash nur im Clear bei der Kontoerstellung übergeben wird (obwohl es Möglichkeiten gibt, dies zu umgehen), und dies sollte auch so sein Sicher vor Wiederholungsangriffen, da der
login_token
bei Verwendung aus der Datenbank entfernt wird.quelle
Das sind eine Menge Fragen in einer, ich denke, 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 nur die gleichen sind, die Sie auf einer Webseite finden würden. Mögliche sehr einfache Optionen wären https für den Anmeldeschritt, die Rückgabe eines Tokens und die Aufnahme in zukünftige Anforderungen. Sie können auch die http-Basisauthentifizierung verwenden und einfach Inhalte in den Header übergeben. Um die Sicherheit zu erhöhen, drehen / verfallen Sie die Token häufig, überprüfen Sie, ob die Anforderungen vom selben IP-Block stammen (dies kann jedoch unordentlich werden, wenn mobile Benutzer zwischen Zellen wechseln), kombinieren Sie sie mit einem API-Schlüssel oder ähnlichem. Alternativ können Sie den Schritt "Anforderungsschlüssel" von oauth ausführen (jemand hat dies bereits in einer vorherigen Antwort vorgeschlagen und es ist eine gute Idee), bevor Sie den Benutzer authentifizieren, und diesen als erforderlichen Schlüssel zum Generieren des Zugriffstokens verwenden.
Eine Alternative, die ich noch nicht verwendet habe, von der ich aber als gerätefreundliche Alternative zu oAuth viel gehört habe, ist xAuth . Schauen Sie es sich an und wenn Sie es verwenden, wäre ich wirklich interessiert zu hören, was Ihre Eindrücke sind.
Für das Hashing ist sha1 ein bisschen besser, aber lassen Sie sich nicht aufhängen - 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 :)
quelle
Was Sie also suchen, ist eine Art serverseitiger Authentifizierungsmechanismus, der die Authentifizierungs- und Autorisierungsaspekte einer mobilen Anwendung behandelt?
Angenommen, dies ist der Fall, würde ich es wie folgt angehen (aber nur, weil ich ein Java-Entwickler bin und ein C # -Typ es anders machen würde):
Der RESTful-Authentifizierungs- und Autorisierungsdienst
Die clientseitige Sicherheitsbibliothek / -anwendung
Nun, da der Blick aus 30.000 Fuß vollständig ist, wie gehen Sie vor? Nun, es ist nicht so schwer, mit einem Browser-Client ein Authentifizierungs- und Autorisierungssystem zu erstellen, das auf den auf der Serverseite aufgeführten Technologien basiert. In Kombination mit HTTPS bieten die Frameworks einen sicheren Prozess, der auf einem gemeinsam genutzten Token (normalerweise als Cookie dargestellt) basiert, das vom Authentifizierungsprozess generiert und verwendet wird, wann immer der Benutzer etwas tun möchte. Dieses Token wird vom Client dem Server bei jeder Anforderung angezeigt.
Bei der lokalen mobilen Anwendung scheinen Sie nach einer Lösung zu suchen, die Folgendes bewirkt:
Was auch immer Sie tun, versuchen nicht, Ihr eigenes Sicherheitsprotokoll zu erfinden oder Sicherheit durch Unbekanntheit zu verwenden. Sie werden niemals einen besseren Algorithmus dafür schreiben können als die derzeit verfügbaren und kostenlosen. Außerdem vertrauen die Leute bekannten Algorithmen. Wenn Sie also sagen, dass Ihre Sicherheitsbibliothek die Autorisierung und Authentifizierung für lokale mobile Anwendungen mithilfe einer Kombination aus SSL-, HTTPS-, SpringSecurity- und AES-verschlüsselten Token bietet, haben Sie sofort Glaubwürdigkeit auf dem Markt.
Hoffe das hilft und viel Glück bei deinem 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.
quelle
Twitter hat das Problem der externen Anwendung in oAuth behoben, indem es eine von ihnen aufgerufene Variante unterstützt xAuth . Leider gibt es bereits eine Vielzahl anderer Schemata mit diesem Namen, so dass es verwirrend sein kann, dies zu klären.
Das Protokoll ist oAuth, außer dass es die Anforderungs-Token-Phase überspringt und einfach sofort nach Zugriff eines Benutzernamens und eines Kennworts ein Zugriffstoken-Paar ausgibt. (Ab Schritt E hier .) Dies erste Anforderung und Antwort muss gesichert sein- Es sendet den Benutzernamen und das Passwort im Klartext und empfängt das Zugriffstoken und das geheime Token zurück. Sobald das Zugriffstokenpaar konfiguriert wurde, ist es für den Client und den Server für den Rest der Sitzung irrelevant, ob der anfängliche Token-Austausch über das oAuth-Modell oder das xAuth-Modell erfolgte. Dies hat den Vorteil, dass Sie die vorhandene oAuth-Infrastruktur nutzen und nahezu dieselbe Implementierung für mobile / Web- / Desktop-Anwendungen verwenden können. Der Hauptnachteil besteht darin, dass der Anwendung Zugriff auf den Benutzernamen und das Kennwort des Clients gewährt wird. Es scheint jedoch, dass Ihre Anforderungen diesen Ansatz vorschreiben.
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 schwer zu erstellen. Je komplizierter sie sind, desto unwahrscheinlicher ist es, dass Ihre Entwickler von Drittanbietern sie gegen sie implementieren können. Ihr hypothetisches Protokoll ist o (x) Auth sehr ähnlich - api_key / api_secret, nonce, sha1 hashing - aber anstatt eine der vielen vorhandenen Bibliotheken verwenden zu können, müssen Ihre Entwickler ihre eigenen rollen.
quelle
Super spät zur Party, aber ich wollte ein paar zusätzliche Punkte einbringen, die jeder berücksichtigen sollte, der sich für dieses Thema interessiert. Ich arbeite für ein Unternehmen, das mobile API-Sicherheitslösungen ( Approov ) anbietet, sodass dieser gesamte Bereich definitiv für meine Interessen relevant ist.
Zunächst ist es wichtig zu berücksichtigen, wie viel es für Sie wert ist, eine mobile API zu sichern . 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:
Dies impliziert, dass für einige API-Aufrufe kein Benutzername / Passwort 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 Bescheinigung der Software. Es gibt keinen Benutzer, aber Sie möchten dennoch sicherstellen, dass kein böswilliger Zugriff auf Ihre API erfolgt. 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 dann das Geheimnis in jeder Version der App preisgeben müssen. Wenn jemand das Geheimnis extrahieren kann, kann er Ihre API verwenden, 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. Die Verschleierung ist ein einfacher Weg, um die Entschlüsselung des Geheimnisses zu erschweren. Es gibt Tools, die dies für Sie tun, insbesondere für Android, aber Sie müssen immer noch Code haben, der Ihren Hash generiert, und eine ausreichend qualifizierte Person kann immer nur die Funktion aufrufen, die das Hashing direkt ausführt.
Eine andere Möglichkeit, die übermäßige Verwendung einer API zu verhindern, für die keine Anmeldung erforderlich ist, besteht darin, den Datenverkehr drosseln und möglicherweise verdächtige IP-Adressen zu identifizieren und zu blockieren. Der Aufwand, den 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. Wie auch immer, es ist ein weiterer Aspekt der Sicherung von APIs, den ich für wichtig halte und den ich melden wollte.
quelle