Laden...

REST Service jeder Client arbeitet mit einer Session

Erstellt von wydy vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.163 Views
W
wydy Themenstarter:in
8 Beiträge seit 2012
vor 11 Jahren
REST Service jeder Client arbeitet mit einer Session

Moin Leute,

ich bin ehrlich gesagt ein ziemlicher Anfänger bei RESTful und habe es erst gerade hinbekommen meinen Service funktionsfähig zu kriegen.
Jetzt möchte ich mehrere Clients haben, welche auf eine Datenbank vom Service zugreifen. Ebenfalls hat jeder Benutzer, welcher den Service nutzt, einen eigenen Login auf der DB und soll ebenfalls immer mit diesem auf die Datenbank zugreifen. Dafür wollte ich eine erste Anfrage generieren mit dem Benutzernamen etc. und dem Benutzer danach eine "Session" zuweisen, welche bei den restlichen Anfragen immer dieselbe ist. Nach Möglichkeit wollte ich der Session ebenfalls eine Lifetime geben, damit der Benutzer nach einer gewissen Zeit eine neue Session anfordern muss.
Wie kann ich das ganze realisieren? Ein Kollege meinte das ganze könne man irgendwie durch session tokens realisieren, welche bei einer Anfrage mitgeliefert werden.

Edit: Google hat mir etwas weitergeholfen und den Beitrag ausgespickt: http://stackoverflow.com/questions/4608225/how-do-i-implement-login-in-a-restful-web-service

Ehrlich gesagt möchte ich nicht bei jeder Anfrage die Benutzerdaten liefern, darum war auch die Idee einer "Session" für jede weitere Anfrage. Aber jetzt bleibt halt die Frage, wie merkt sich der Server das "accesstokens" für die nächsten Anfragen? Selbst ein Singleton wird bei der nächsten Anfrage verworfen.

G
538 Beiträge seit 2008
vor 11 Jahren

Für eine Session-Basierte authentifizierung, würdest du klassischerweise wohl ein Session-Cookie erzeugen, das eine genügend Randomisierte generierte Zahl enthält, die du dann mitsendest.
Auf Serverseite speicherst du das entweder in HTTPContext.Session (das ist allerdings wohl nicht "REST-Konform" (sofern es letzteres überhaupt gibt) oder du speicherst es in eine Datenbank (macht auch ne Serverseitige Session).
Du kannst aber auch sowas wie NTLM oder die Basic-Authentifizierung benutzen, dabei wird jedesmal die Authentifizierung mitgesendet (was im Kontext von REST wohl der "richtige" Weg wäre).

Zwei Dinge:

  1. REST als solches sollte Zustandslos sein (so sagt es zumindest Wiki)
  2. Da du offensichtlich HTTP verwendest, solltest du auch HTTP-Standard-Mechanismen zur Authentifizierung verwenden.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

W
wydy Themenstarter:in
8 Beiträge seit 2012
vor 11 Jahren

Ich habe das ganze jetzt wohl etwas unkonventionell gelöst.

Der Benutzer sendet ein POST an den Server auf das Verzeichnis /token. Dabei übermittelt der Benutzer seinen Benutzernamen und das Passwort, dieses ist dabei synchron verschlüsselt.

Der Server versucht dann mit den Benutzerdaten sich auf der Datenbank einzuloggen. Funktioniert der Login nicht, sendet der Server einen leeren "Token" an den Client zurück. Funktioniert der Login werden die Datenbankverbindung und die Logindaten in einem Singleton gespeichert. Danach wird dem Benutzer eine Lifetime und ein zufällig generiertes Token zugewiesen. Dieses Token wird dann an den Client zurückgesendet.

Die restlichen Anfragen vom Client gehen danach immer über dieses Token. Bei der Anfrage wird anfänglich immer kontrolliert ob die Lifetime abgelaufen ist und gegebenenfalls ein Fehler an den Client gesendet.

Das hinzufügen und löschen von Benutzer in Singleton ist in einem lock(user), damit nicht mehrere Anfragen die Benutzerdaten gegenseitig überschreiben.

Das ganze funktioniert ohne Probleme, nur ist dabei das Passwort nur synchron verschlüsselt und könnte abgehört/entschlüsselt werden.

Edit: Dabei habe ich aber noch eine Frage. Das Token, welches ich zurücksende hat folgendes Aussehen:


    [DataContract]
    public class TokenRest
    {
        [DataMember]
        public string token { get; set; }

        public TokenRest()
        {
            this.token = "";
        }
    }

Für eine einfache Variable eine eigene Klasse zu verwenden ist doch etwas übertrieben. Gibt es eine andere Variante die Variable zurückzusenden?

G
538 Beiträge seit 2008
vor 11 Jahren

Unkonventionell - ja ...

also deine Verschlüsselung kannst du dir (wenn sie Synchron ist) getrost sparen - synchrone verschlüsselung mit öffentlichen Schlüsseln bringt in etwa .... nichts. ((Deshalb war auch dieses Xpire-Bild-selbst-lösch-System nichts wert)

Viel wichtiger wäre es das ganze in HTTPS (oder ein anderes asynchrones Verschlüsselungsverfahren) zu kapseln, aber das nur am Rande.

Du könntest anstatt diese Antwort zu senden auch ein Cookie senden, wo du genau den String reinschreibst.
Egal wie - da REST ja eher JSON und XML spricht anstatt von Klassen kannst du sicherlich (hab's nicht geprüft - ich vermute nur grade) auch einfach einen String zurückgeben.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

W
wydy Themenstarter:in
8 Beiträge seit 2012
vor 11 Jahren

Jep darin stimm ich mit dir überein.
Das ganze ist auch nur eine Schularbeit und die synchrone Verschlüsselung ist nur dafür da um mehr Punkte zu kriegen 😄. Wir werden in der Abschlussdokumentation auch klar erwähnen, dass es sich nur um einen Prototypen handelt und in einem späteren Schritt eine SSL Verschlüsslung angebracht wäre. Es reicht einfach schlichtweg die Zeit nicht das ganze SSL zu verschlüsseln.

G
538 Beiträge seit 2008
vor 11 Jahren

ähm.. es reicht die Zeit nicht?
Klingt kompliziert SSL auf dem Server anzuschalten und im Client statt http https hinzuschreiben 😉

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

W
wydy Themenstarter:in
8 Beiträge seit 2012
vor 11 Jahren

ähm.. es reicht die Zeit nicht?
Klingt kompliziert SSL auf dem Server anzuschalten und im Client statt http https hinzuschreiben 😉

Hm die Studienkollegen meinten, man müsse ein eigenes Zertifikat generieren, dass müsse man dann auf dem Server installieren und sie hätten damit nur Probleme gehabt...
Da haben wirs einfach gelassen.
Unser Server besteht aus einer simplen "WCF Service Application". Kann man das dort einfach einstellen? Wenn ja wie? 😄

G
538 Beiträge seit 2008
vor 11 Jahren

CodeProject weiß etwas zu SSL auf Self-hosted-Services.

Wenn dein Service im IIS läuft ist's noch einfacher, weil man das dort mit dem seinen Einstellungen abhandeln kann.

Sieh's als Kür für dein Schulprojekt 😉

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)