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:
- Client & Server befinden sich in .NET4 (Client-Teil im Client-Profil)
- Server macht mit WCF REST verfügbar
- 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:
- Bevor der Client versucht, sich zu authentifizieren, generiert er mithilfe der
ECDiffieHellmanCng
Klasse ein Diffie-Hellman-Schlüsselpaar . - Es sendet den öffentlichen Teil des Schlüsselpaars zusammen mit dem Benutzernamen und dem Kennwort über das Kabel (natürlich über HTTPS).
- Der Server authentifiziert die Kombination aus Benutzername und Kennwort. Wenn dies erfolgreich ist, führt er Folgendes aus:
- Erstellt ein eindeutiges Sitzungstoken
- Generiert ein eigenes DH-Schlüsselpaar und berechnet das gemeinsame Geheimnis aus dem vom Client bereitgestellten öffentlichen Schlüssel
- 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
- Gibt das Sitzungstoken, seinen öffentlichen DH-Schlüssel und eine Authentifizierungserfolgsnachricht zurück
- 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?
quelle
Antworten:
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.
quelle
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
quelle