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.
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.
Ein externer Entwickler fordert ein API-Konto an. Sie erhalten einen Apikey und Apisecret. Für jede Anforderung sind mindestens drei Parameter erforderlich.
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.
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.
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?
Die Art und Weise, wie ich daran denke, den Login-Teil davon in meinen Projekten zu machen, ist:
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.
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.
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.
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 :)
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.
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
Die clientseitige Sicherheitsbibliothek/-anwendung
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:
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.
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:
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.