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?