Entwerfen der Authentifizierung für die REST-API

11

Ich arbeite an einer API für einen REST-Service, den ich sowohl produzieren als auch konsumieren werde. Ich habe in den letzten Tagen versucht, herauszufinden, wie man mit Authentifizierung gut umgeht, und denke, ich habe mir endlich etwas ausgedacht.

Ich komme auf die Grundlage der folgenden Fakten zum Anwendungsstapel:

  1. Client & Server befinden sich in .NET4 (Client-Teil im Client-Profil)
  2. Server macht mit WCF REST verfügbar
  3. Ich möchte den Benutzernamen und das Passwort in der App wirklich nicht im Speicher behalten

Ab 3 wollte ich eine Form der Token-Authentifizierung verwenden, damit der Client nach Überprüfung der Anmeldeinformationen durch den Server ein Token zurückerhält, das im gesamten Rest der App verwendet werden kann (dies ermöglicht mir andere Aufgaben, z Zeitüberschreitung bei Benutzern, nahtlose Verschiebung von Benutzern zwischen der Web- und Desktop-Version usw.). Nachdem ich herausgefunden habe, wie die Anrufe wiederholt und manipulationssicher gemacht werden können, habe ich Folgendes gefunden:

  1. Bevor der Client versucht, sich zu authentifizieren, generiert er mithilfe der ECDiffieHellmanCngKlasse ein Diffie-Hellman-Schlüsselpaar .
  2. Es sendet den öffentlichen Teil des Schlüsselpaars zusammen mit dem Benutzernamen und dem Kennwort über das Kabel (natürlich über HTTPS).
  3. Der Server authentifiziert die Kombination aus Benutzername und Kennwort. Wenn dies erfolgreich ist, führt er Folgendes aus:
    1. Erstellt ein eindeutiges Sitzungstoken
    2. Generiert ein eigenes DH-Schlüsselpaar und berechnet das gemeinsame Geheimnis aus dem vom Client bereitgestellten öffentlichen Schlüssel
    3. Notiert das Sitzungstoken, das gemeinsame Geheimnis, den Benutzer und die Zeit der "letzten Aktion" (die für ein fortlaufendes Ablauffenster verwendet wird) in seiner Datenbank
    4. Gibt das Sitzungstoken, seinen öffentlichen DH-Schlüssel und eine Authentifizierungserfolgsnachricht zurück
  4. Der Client entnimmt der Antwort den DH-Schlüssel, berechnet das gemeinsame Geheimnis und speichert sowohl das Token als auch das Geheimnis im Speicher.

Ab diesem Zeitpunkt funktioniert die Kombination aus Sitzungstoken und Geheimnis wie die meisten anderen REST-APIs. Die Anforderung wird mit einem Fingerabdruck versehen und mit einem Zeitstempel versehen. Anschließend wird eine Art HMAC generiert. Wenn ein Client eine Aktion für den Server ausführt, überprüft er das Token / Secret-Paar und lässt die Aktion zu, wenn sie gültig und nicht abgelaufen ist, und aktualisiert den letzten Aktionsdatensatz in der Sitzung.

Ich sehe keine offensichtlichen Mängel und bin wahrscheinlich dafür überentwickelt, aber ich muss irgendwann lernen, wie man das macht. Der HMAC verhindert Wiederholungsangriffe, die DH-Aushandlung hilft, MITM-Angriffe zu verhindern (ich kann mir keinen praktikablen Angriff zwischen HMAC / DH vorstellen).

Irgendwelche Löcher, in die jemand stecken kann?

Matt Sieker
quelle
Ich sehe nicht, wie das Generieren der DH-Schlüssel überhaupt Sicherheit bringt, verglichen mit der einfachen Verwendung von HTTPS überall und der Verwendung eines einfachen alten Sitzungscookies. Bei ordnungsgemäßer Verwendung schützt HTTPS bereits vor Man-in-the-Middle- und Wiederholungsangriffen.
Lie Ryan

Antworten:

5

Anstatt Ihre eigene zu erfinden, sollten Sie die OpenAM-API lesen und ausleihen.

http://forgerock.com/openam.html

Das OpenAM Wiki ist besonders hilfreich

https://wikis.forgerock.org/confluence/display/openam/Home

Sie müssen ihre Komponenten nicht verwenden. Wenn Sie jedoch ihre API verwenden, werden Sie feststellen, dass Ihr Leben auf lange Sicht einfacher wird.

S.Lott
quelle
Hmm, es sieht nicht schlecht aus, eine Sache, die mich in diesem Fall daran hindert, es zu benutzen: Wir sind ein .Net-Shop. Außerdem ist es nicht sehr wichtig, es auf der WCF-Serverseite zu verwenden. Der einzige Nicht-Spam-Link, den ich bei Google finden konnte, weist auf die Verwendung von WIF und WS-Federation hin.
Matt Sieker
1
@ Matt Sieker: "Sie müssen ihre Komponenten nicht verwenden". Bitte lesen Sie über ihre API, anstatt Ihre eigene zu erfinden.
S.Lott
Ah, ich glaube ich verstehe was du meinst, die Anforderungen Rückruf Sachen. Das ist interessant, ich könnte das genauer untersuchen, wenn nicht für dieses Projekt, für zukünftige. Anstatt auth als einen atomaren Block auszuführen, teilen Sie ihn leicht auf, damit der Server vom Client aus steuern kann, was er benötigt ...
Matt Sieker
Wir haben zunächst unsere eigenen gerollt, sind dann aber vor einigen Jahren bei der IG Group zu OpenAM gewechselt. Sehr zufrieden mit dem Open Source Produkt.
Robert Morschel
2

Ich stimme @ S.Lott zu 100% zu, dass Sie nicht Ihre eigenen rollen wollen. Ich schlage vor, eine andere Alternative in Betracht zu ziehen: den Windows Azure Access Control Service (ACS). ACS kostet Geld, ist aber sehr billig (10.000 Transaktionen für 0,01 USD) und es wird viel Infrastruktur abgewickelt. WIF wird auf dem Client genutzt.

Dies ist auch eine auf Standards / Ansprüchen basierende Lösung - was der letzte Schrei ist. Lesen Sie diesen Artikel über die gemeinsame Verwendung von WCF, REST und ACS .

Wenn Sie an die Zukunft denken, ist dies auch ein Mechanismus, der mit Ihnen wachsen kann - da Sie mobile Apps außerhalb der Firewall, Partner usw. haben. Auch wenn Sie es nicht verwenden möchten, da es eine Abhängigkeit außerhalb Ihrer Firewall hinzufügt, sollten Sie es auf Ideen überprüfen. Sehr glatt.

Viel Glück! -Rechnung

Codierung laut
quelle