Ich arbeite derzeit an einer REST-Bibliothek für .net und würde gerne einige Meinungen zu einem offenen Punkt hören, den ich habe: REST und Authentifizierung.
Hier ist ein Beispiel für eine RESTful-Schnittstelle, die mit der Bibliothek verwendet wird:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
Der Servercode implementiert dann nur die Schnittstelle und die Clients können dieselbe Schnittstelle über eine Factory erhalten. Wenn der Client die Bibliothek nicht verwendet, funktioniert auch eine Standard-HTTP-Anforderung.
Ich weiß, dass es die wichtigsten Möglichkeiten gibt, entweder HTTP Basic Auth zu verwenden oder ein Token an Anforderungen zu senden, die authentifizierte Benutzer erfordern.
Die erste Methode (HTTP Basic Auth) weist die folgenden Probleme auf (teilweise Webbrowserspezifisch):
- Das Passwort wird bei jeder Anfrage übertragen - auch bei SSL hat dies ein "schlechtes Gefühl".
- Da das Passwort mit einem Anforderungsheader übertragen wird, kann ein lokaler Angreifer leicht auf die übertragenen Header schauen, um das Passwort zu erhalten.
- Das Passwort ist im Speicher des Browsers verfügbar.
- Keine Standardmethode zum Ablaufen von Benutzersitzungen.
- Die Anmeldung mit einem Browser unterbricht das Erscheinungsbild einer Seite.
Die Probleme bei der zweiten Methode konzentrieren sich mehr auf die Implementierung und die Verwendung der Bibliothek:
- Jeder Anforderungs-URI, der eine Authentifizierung benötigt, muss einen Parameter für das Token haben, der sich nur sehr wiederholt.
- Es muss viel mehr Code geschrieben werden, wenn bei jeder Methodenimplementierung überprüft werden muss, ob ein Token gültig ist.
- Die Schnittstelle wird weniger spezifisch, z . B.
[RestGet("/get/{id}")]
vs.[RestGet("/get/{id}/{token}")]
- Wo soll der Token abgelegt werden: am Ende der URI? nach der Wurzel? irgendwo anders?
Meine Idee war, das Token als Parameter an die URL wie zu übergeben http:/server/user/get/1234?token=token_id
.
Eine andere Möglichkeit wäre, den Parameter als HTTP-Header zu senden, aber dies würde die Verwendung mit einfachen HTTP-Clients erschweren, denke ich.
Das Token wird bei jeder Anforderung als benutzerdefinierter HTTP-Header ("X-Session-ID") an den Client zurückgegeben.
Dies könnte dann vollständig von der Schnittstelle abstrahiert werden, und jede Implementierung, die eine Authentifizierung benötigt, könnte nur fragen, zu welchem Benutzer das Token (falls angegeben) gehört.
Glaubst du, dies würde REST zu sehr verletzen oder hast du bessere Ideen?
quelle
Ich stimme workmad3 zu. Wenn die Sitzungslebensdauer eingehalten werden muss, sollten Sie eine Sitzungsressource erstellen. Das Posten auf dieser Ressource mit Benutzeranmeldeinformationen (entweder Basisauthentifizierung oder Anmeldeinformationen im Hauptinhalt) gibt eine eindeutige Sitzungs-ID zurück. Durch Löschen in / session / {id} wird der Benutzer abgemeldet.
Wenn Sie die Ablaufzeit der Sitzung steuern möchten. Beim Erstellen einer neuen Sitzung (Post on Session Resource) setzt der Server ein Cookie für die Antwort (unter Verwendung des Standard-Set-Cookie-Headers). Der Cookie enthält eine Ablaufzeit. Die Cookie-Zeichenfolge sollte auf dem Server verschlüsselt sein, damit nur der Server dieses Cookie öffnen kann. Bei jeder nachfolgenden Anforderung an den Server wird das Sitzungscookie im Cookie-Header gesendet. (Dies wird automatisch für Sie erledigt, wenn Ihr Client ein Browser ist.) Der Server muss das Cookie für jede Anforderung "erneuern", dh ein neues Cookie mit einer neuen Ablaufzeit erstellen (Timeout der Sitzung verlängern). Denken Sie daran, das Cookie zu löschen, wenn der Benutzer delete für die Sitzungsressource aufruft.
Wenn Sie möchten, dass Ihre Anwendung sicherer ist, können Sie die Client-IP im Cookie selbst speichern. Wenn also eine Anforderung eingeht, kann der Server überprüfen, ob sie vom "ursprünglichen" Client gesendet wurde. Denken Sie jedoch daran, dass diese Lösung problematisch sein kann, wenn Proxys beteiligt sind, da der Server möglicherweise alle Anforderungen als vom selben Client stammend "sieht".
quelle
Die Restauthentifizierung, die ich gesehen habe, behandelt die Sitzungen als REST-Ressource für die Erstellung, Zerstörung usw., und dann wird die Sitzungs-ID hin und her übergeben. Diejenigen, die ich gesehen habe, neigen dazu, das Sitzungscookie dafür zu verwenden, da dies die einzige Möglichkeit ist, es wirklich zu sichern. Wenn Sie die Sitzungs-ID in der URL übergeben, können Sie nicht wirklich authentifizieren, dass sie vom richtigen Client stammt.
Die Authentifizierung ist jedoch ein heikles Problem bei REST, da eine Form des Status außerhalb der URL aufbewahrt werden muss, was gegen die REST-Prinzipien verstößt, dass die URL alles ist, was zur Darstellung des Status erforderlich ist.
quelle