REST Webservice absichern?

Django, Flask, Bottle, WSGI, CGI…
Antworten
metty
User
Beiträge: 99
Registriert: Samstag 13. Dezember 2008, 19:30

Hallo zusammen,

ich brüte derzeit über einer Authentifizierungs-Möglichkeit für einen REST Webservice.

Hintergrund ist der:
Ich möchte für einen Blog, der auf django basiert, eine API-Schnittstelle schaffen wo berechtigte Personen via "POST" XML/JSON-Daten an den Webservice übermitteln können. Es soll dabei auf Sessions usw. verzichtet werden. Die Übertragung wird mit SSL verschlüsselt.

OAuth, OpenID etc. sind mir bekannt, sind aber für meinen kleinen Fall Overkill.

Mein Lösungsvorschlag wäre:
Der Benutzer erhält einen AUTHKEY und einen SECRETAUTHKEY.
Den AUTHKEY übermittelt er beim Aufrufen der URI z.B.

https://tollerserver.de/api/sendpost?AUTHKEY=xxxxxxxxx

Über den AUTHKEY wird im Endeffekt der User ermittelt und überprüft ob er die API nutzen darf. (Statt des AUTHKEY wäre auch ein simpler HTTP Basic Auth ausreichend, da die Übertragung ja via SSL verschlüsselt wird.)Wenn er die API nutzen darf, kann er seine XML/JSON-Daten übertragen. In den XML/JSON-Daten ist dann der SECRETAUTHKEY enthalten, der mehr oder weniger sicherstellen soll, das die übertragenen Daten auch wirklich von der berechtigen Person stammen.

XML-Beispiel:

Code: Alles auswählen

<POST>
    <AUTHENTICATION>
        <SECRETAUTHKEY>yyyyyyyyyyyy</SECRETAUTHKEY>
    </AUTHENTICATION>
    <DATA>
        ...
    </DATA>
</POST>
Erst wenn der SECRETAUTHKEY zu dem für den User hinterlegten SECRETAUTHKEY passt, werden die Daten verarbeitet, ansonsten verworfen.
Ich habe mir APIs verschiedener Websites angesehen, die übertragen oft nur einen API-Key, den sie für die Authentifizierung verwenden.

Habt ihr andere Lösungsvorschläge? Wie ist eure Meinung dazu?

Ich freue mich immer über Anregungen.
Zuletzt geändert von metty am Freitag 23. April 2010, 16:28, insgesamt 2-mal geändert.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wenn du SSL nutzt, solltest du doch auch http basic auth nutzten können.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
noisefloor
User
Beiträge: 3858
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich verstehe gerade den Sinn der doppelten Authentifizierung nicht. Kann man machen, ist aber IMHO "doppelt gemoppelt".

Persönlich finde ich, dass die Übertragung des AUTHKEY in der URL für den Nutzer nicht sonderlich komfortabel ist - schließlich muss er die URL ja dann händisch bauen. Dann lieber HTTP-Basic, da liefert der Browser zumindest ein Pop-Up Fenster mit Eingabefeldern. :-)

Gruß, noisefloor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

noisefloor hat geschrieben:ich verstehe gerade den Sinn der doppelten Authentifizierung nicht. Kann man machen, ist aber IMHO "doppelt gemoppelt".
Was ist denn da doppelt?
noisefloor hat geschrieben:Persönlich finde ich, dass die Übertragung des AUTHKEY in der URL für den Nutzer nicht sonderlich komfortabel ist - schließlich muss er die URL ja dann händisch bauen. Dann lieber HTTP-Basic, da liefert der Browser zumindest ein Pop-Up Fenster mit Eingabefeldern. :-)
Das ist ein Webservice...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Ist es nicht gerade der Sinn von REST, durch die Nutzung von bekannten und erprobten Standards möglichst kompatibel zu sein? HTTP auth existiert, ist weit verbreitet und wohl definiert. Ich sehe keinen Grund, warum du etwas Eigenes basteln solltest.
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
noisefloor
User
Beiträge: 3858
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Was ist denn da doppelt?
1. Auth: Login auf der Seite
2. Auth: Innerhalb der zu übertragenden Datei, die man über die Seite hochlädt, auf die man sich zuvor eingeloggt hat.

Gruß, noisefloor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

noisefloor hat geschrieben:1. Auth: Login auf der Seite
2. Auth: Innerhalb der zu übertragenden Datei, die man über die Seite hochlädt, auf die man sich zuvor eingeloggt hat.
Das eine ist Auth für User, das andere ist Auth für Webservice-Konsumenten. Letztere wollen sich gar nicht auf der Seite anmelden sondern nur irgendwas über die API machen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Leonidas hat geschrieben:
noisefloor hat geschrieben:1. Auth: Login auf der Seite
2. Auth: Innerhalb der zu übertragenden Datei, die man über die Seite hochlädt, auf die man sich zuvor eingeloggt hat.
Das eine ist Auth für User, das andere ist Auth für Webservice-Konsumenten. Letztere wollen sich gar nicht auf der Seite anmelden sondern nur irgendwas über die API machen.
In dem Post vom OP existiert diese Trennung aber nicht wirklich, habe es auch wie "noisefloor" verstanden...
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
metty
User
Beiträge: 99
Registriert: Samstag 13. Dezember 2008, 19:30

noisefloor hat geschrieben:ich verstehe gerade den Sinn der doppelten Authentifizierung nicht. Kann man machen, ist aber IMHO "doppelt gemoppelt".

Persönlich finde ich, dass die Übertragung des AUTHKEY in der URL für den Nutzer nicht sonderlich komfortabel ist - schließlich muss er die URL ja dann händisch bauen. Dann lieber HTTP-Basic, da liefert der Browser zumindest ein Pop-Up Fenster mit Eingabefeldern. :-)
Das ist eigentlich nicht doppelt gemeint...
Der Benutzer soll sich ja nicht über den Browser anmelden um etwas über ein Formular hochladen...

Ich will eine API bereitstellen, die XML/JSON Daten entgegennimmt.
So kann sich der Benutzer z.B. ein Desktop-App schreiben, das seine eingegeben Daten in XML/JSON umwandelt und an die REST-Schnittstelle "https://tollerserver.de/api/sendpost" sendet.

Die in deinen Augen "doppelte" Authentifizierung soll dabei folgenden Problemen vorbeugen:

1. Jemand der keinen AUTHKEY hat, oder einen falsche angibt, soll gar nicht erst seine XML/JSON oder "whatever" Daten an die Schnittstelle senden können und gleich einen 403 Forbidden bekommen. Zudem wird über den AUTHKEY der Nutzer bestimmt. (Das könnte man natürlich auch mit Basic Auth machen)

2. Ist ein AUTHKEY "zufällig" doch in fremde Hände geraten, so dient der SECRETAUTHKEY quasi als "Signatur" für das übertragene XML/JSON Dokument. Sprich, nur wenn der AUTHKEY und der SECRETAUTHKEY für einen bestimmten Benutzer übereinstimmen, sollen die Daten überhaupt erst weiterverarbeitet werden.

Natürlich liese sich die 1. Authentifizierung über Basic Auth lösen, aber wenn ich mir die APIs vieler Seiten so ansehe, verwenden doch viele die Möglichkeit mit dem AUTHKEY. Bei denen heißt das meistens APIKEY und wird auch oft als Parameter ala "server.de/api/aufruf?APIKEY=xxxx" angehängt.

Ich hoffe ich konnte ein wenig Klarheit schaffen.
Zuletzt geändert von metty am Freitag 23. April 2010, 17:04, insgesamt 2-mal geändert.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Was ist an Basic-Auth nicht komfortabel? So gut wie jede HTTP Bibliothek hat da eingebauten support für, wohingegen für deine properitäre Lösung extra noch an den XML Daten rum hantiert werden muss. Außerdem fügst du eine unnötige Ebene in dein Daten-Format ein. Warum "POST->DATA->content" wenn purer "content" völlig ausreichen würde?
Bottle: Micro Web Framework + Development Blog
metty
User
Beiträge: 99
Registriert: Samstag 13. Dezember 2008, 19:30

Defnull hat geschrieben:Was ist an Basic-Auth nicht komfortabel? So gut wie jede HTTP Bibliothek hat da eingebauten support für, wohingegen für deine properitäre Lösung extra noch an den XML Daten rum hantiert werden muss. Außerdem fügst du eine unnötige Ebene in dein Daten-Format ein. Warum "POST->DATA->content" wenn purer "content" völlig ausreichen würde?
Natürlich ist Basic Auth auch komfortabel, ich habe meinen Post nur vorschnell losgelassen und ihn nochmals geändert.
Mein XML-Schema würde im Produktivbetrieb natürlich anders aussehen, aber ich wollte es für den Post übersichtlicher gestalten. (JSON wäre mir sowieso sympathischer :D)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

ich würde ebenfalls basic auth über SSL benutzen. Wenn man Angst hat, dass das User+Password-Paar in fremde Hände geraten könnte, ändert man z.B. das Password häufiger betrachtet es als auth-key. Dennoch würde ich das bekannte Verfahren benutzen, denn das ist eigentlich schon in allen Bibliotheken eingebaut und man muss da nichts eigenes entwerfen.

Stefan
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

sma hat geschrieben:ich würde ebenfalls basic auth über SSL benutzen. Wenn man Angst hat, dass das User+Password-Paar in fremde Hände geraten könnte, ändert man z.B. das Password häufiger betrachtet es als auth-key. Dennoch würde ich das bekannte Verfahren benutzen, denn das ist eigentlich schon in allen Bibliotheken eingebaut und man muss da nichts eigenes entwerfen.

Stefan
Oder gleich direkt über SSL authentifizieren.

Auf jeden Fall gehören Authentifizierungsschlüssel nicht und nie in den QueryString. Auch in den Request Body würde ich es nicht schreiben. Löse das ganze auch HTTP oder SSL ebene.

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Antworten