Sicherheit bei REST-Webservice

DakineVester

Mitglied
Hallo zusammen,

ich habe einige Fragen bezüglich der Sicherheit bei REST-Webservies. Aber zunächst einmal ein paar Erklärungen zu dem geplaten Service.

Im Rahmen eines Projektes möchte ich einen Webservice erstellen, der zwei PDF-Dokumente verarbeitet und daraus ein drittes PDF-Dokument erstellt. Dabei habe ich mir es so vorgestellt, dass zuerst die Dokumente per FTP bzw. FTPS auf den entsprechenden Server geladen werden und nach erfolgreicher Übertragung der Webservice-Client aufgerufen werden soll. Dieser führt einen GET-Request aus und bekommt als Antwort den Pfad zum dritten Dokument. Danach soll halt ein FTPS-Download erfolgen.

Zuerst einmal eine Grundsätzliche Frage: Ist für diese Art von Service die REST-Methode tatsächlich die richtge?

Und nun zum eigentlichen Punkt:
Sicherheit spielt bei dem Projekt auch eine große Rolle. Deshalb die Frage, wie schützt man den Webservice am besten, und weitergehend, wie wird die Übertragung am besten verschlüsselt?

Nach meinen bisherigen Recherchen hat sich ergeben, dass die einfachste Methode, einen REST-Webservice zu sichern, die Http-Basis-Authentifizierung ist. Gibt es noch gute/bessere Alternativen? Für die verschlüsselte Übertragung ist nach meinem Kenntnisstand SSL eine gute Methode. Gibt es hierfür noch Alternativen?

Da ich noch Neuling bin im Bereich Webservice und auch im Bereich Java, ist mir jede konstruktive Kritik recht. Auch wenn die Vorgehensweise grundsätzlich unstimmig ist und beispielsweise der Einsatz von SOAP sinnvoller wäre.

Ich hoffe ihr könnt mir hilfreiche Tipps geben.
Gruß, Hendrik
 

Noctarius

Top Contributor
Ob das mit dem FTPS alles so gut ist bin ich mir nicht sicher, kommt aber auf den Verwendungszweck an. Ich würde eher per PUT ein neues "Enddokument" erstellen, per POST Mergefiles hinzufügen und per GET abholen. Dann könnte man auch sauber mit den REST-URIs arbeiten.

Sicherheit würde ist Stateless per Basic-Auth herstellen. Ergo meldet sich der Client quasi bei jedem Request über HTTP Header am Server an. Die Verbindung per HTTPS verschlüsselt und ein ausreichendes Sicherheitslevel sollte gegeben sein. Dies reicht zu mindestens für unsere sensiblen Bewerber- und Testdaten ;-)
 

DakineVester

Mitglied
Okay, die Bereitstellung der Dokumente werde ich nochmal überdenken. Nur um mich nochmal zu vergewissern, dass ich das richtig verstanden habe. Du würdest zunächst per POST die Dokumente dem Webservice bereitstellen, dann per PUT das Enddokument erstellen lassen, und dieses dann per GET "abholen"?

Das Problem dabei ist, dass ich ja theoretisch per GET direkt das PDF-Dokument Anfragen kann, allerdings dabei keine Fehlermeldungen geliefert werden können (bis auf den HTTP-Status). Deswegen würde ich gerne als GET-Response wahrscheinlich Text nehmen. So kann ich dem Client sagen, dass z.b. Kriterien für die Erstellung des Enddokuments nicht richtig waren.

Eine weitere Frage ist die Zeitenoptimierung und die Auslastung der Kapazitäten des Servers. Wahrscheinlich wird der Webservice später mehrere Zugriffe gleichzeitig verarbeiten müssen. Aus dem Grund hatte ich gedacht, dass FTP sinnvoll ist und schneller ist als die HTTP POST Methode. Wenn das nicht der Fall ist, würde die POST-Methode sinnvoller bzw. einfacher sein.

Zur Sicherheit: Da bin ich bei meiner eigenen Recherche auch zu dem Entschluss gekommen, die Authentifizierung per Basic Authentication zu realisieren und die Datenübertragung per HTTPS abzusichern. Denke das sollte für das Projekt ausreichen.
 
Zuletzt bearbeitet:

Noctarius

Top Contributor
PUT /service/document -> neue Document Id 123456
POST /service/document/123456 <- erstes Document schicken
POST /service/document/123456 <- zweites Document schicken
GET /service/document/123456 -> zusammengesetztes Document abholen, alternativ halt einen Fehler

Sollte das Document noch nicht zusammengebaut sein kannst du einen entsprechenden HTTP Code zurückliefern und definieren, dass der Client nach kurzer Wartezeit erneut anfragen soll, z.B. 412 (Precondition failed).
 
G

Gelöschtes Mitglied 5909

Gast
&mdash; Project Kenai kann ich dir da Empfehlen.

Absichern kannst du das dann etwa so:

Java:
@Context 
SecurityContext securityContext

@POST
@Path("/document")
@Consumes({MediaType.APPLICATION_JSON})
public void sendDocument(Document document) {
  if (!securityContext.isUserInRole("Rolle") {
      throw new WebApplicationException(); // statuscode fobiddden setzten
  } 
  // verarbeiten
   
}
 

DakineVester

Mitglied
Guten Morgen zusammen,

besten Dank schonmal für eure Beiträge! Ich werde mich heute mal damit beschäftigen, die Daten per POST dem Webservice zur Verarbeitung bereitzustellen. Für meine bisherigen Versuche habe ich mit dem Projekt Jersey gearbeitet, werde aber heute mich aber heute mal mit Spring beschäftigen. Wie gesagt, ich bin eigentlich Neueinsteiger was Java angeht.

Auch wie ich mit dem securityContext umgehen muss (wie ich z.B. die vorherige Authentifizierung durchführe. Ich vermute mal so auf Anhieb, dass es lediglich die Abfrage ist, ob die HTTPBasicAuth erfolgreich war.)

Mich wundert allerdings immer noch, dass die Übertragung der Dokumente per HTTP und nicht per FTP umgesetzt werden kann/soll. Ich hätte vermutet, dass eine FTP Übertragung schneller (bzw. ohne weniger Headerdaten) ist und da unabhängig vom eigentlichen Webservice, diesen ein wenig entlastet. Denn das wird ein wichtiger Punkt sein, da die Verarbeitung der Dokumente und die Erstellung des Enddokuments einiges an Rechenleistung in Anspruch nimmt. Auch die Zahl der Zugriffe wird vermutlich nicht gering bleiben.
 
G

Gelöschtes Mitglied 5909

Gast
Basic Auth geht per web.xml (Mit Spring Security wirds auch gehn):

[xml]
<!-- BASIC Authentication -->

<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Admin</realm-name> <!-- hier den realm aus der server.xml angeben -->
</login-config>

<security-role>
<role-name>upload</role-name>
</security-role>

<security-constraint>
<web-resource-collection>
<web-resource-name>upload</web-resource-name> <!-- Rest Servlet -->
<url-pattern>/*</url-pattern> <!-- hier die geschützte url -->
</web-resource-collection>
<auth-constraint>
<role-name>upload</role-name>
<!-- rolle die benötigt wird (kann auch Methodengenau mit dem SecurityContext überprüft werden -->
</auth-constraint>
</security-constraint>
[/xml]
 

DakineVester

Mitglied
Ich denke ich bin gestern ein gutes Stück voran gekommen. Habe das Buch RESTful Java with JAX-RS von O'Reilly gelesen und meinen Webservice dann wie folgt aufgebaut:

POST -> erstes Dokument "hochladen"
POST -> zweites Dokument "hochladen"
PUT -> Enddokument erstellen
GET -> Enddokument herunterladen

So sollte das eher einem REST-Webservice entsprechen als mein vorheriger Ansatz.

Die Basic-Authentifizierung konnte ich auch soweit lösen, allerdings muss ich diese noch optimieren, da ich quasi bei jedem POST/PUT/GET eine neue Verbindung aufbaue und mich demnach neu authentifiziere.

Wo ich gerade dran sitze ist die Umsetzung ins HTTPS. Wird zwar auch im oben genannten Buch erwähnt und mit einem kurzen Beispiel erklärt, aber das verstehe ich noch nicht so ganz und das Implementieren des Beispiels in meinen Webservice klappt auch noch nicht so. Anscheinend gibt es Probleme mit "DerInputStream.getLength" beim Einlesen des Keys. Google sagt mir falsch Class eingebunden. Mal sehen wie ich das genau lösen kann.

Ab hier sollte ich aber alleine zu recht finden. Besten Dank für eure Hilfe! Meine Fragen bzgl. der Sicherheit wurden beantwortet und der Verbesserungsvorschlag zum allgemeinen Vorgehen war auch sehr hilfreich!
 
Zuletzt bearbeitet:

Noctarius

Top Contributor
Ich würde die hochgeladenen Documents feste einen Enddokument zuordnen. Was machst du denn wenn hinterher 20 Leute gleichzeitig ihre Docs einstellen?

PUT /service/document -> neue Document Id 123456
PUT /service/document/123456/document/1 <- erstes Document schicken
PUT /service/document/123456/document/2 <- zweites Document schicken
GET /service/document/123456 -> zusammengesetztes Document abholen, alternativ halt einen Fehler

So z.B. wäre es auch gut, dann kannst du gleich noch eine Reihenfolge vorgeben aber in beliebiger Hochladen (z.B. paralleler Upload).
 

DakineVester

Mitglied
Eigentlich sollte das Hochladen von 20 Dokuemten gleichzeititg kein Problem sein, da die Dateien jeweils in einem Benutzerspezifischen Ordner abgelegt werden und der PUT-Befehl ebenfalls dem Webservice sagt, welche Dateien er "anpacken" soll, bzw. aus welchen er das Enddokument erstellen soll.

Quasi:

POST ../document/save/usrname/timestamp/doc1/blabla.pdf
POST ../document/save/usrname/timestamp/doc2/blubbl.pdf
>> Es liegen dann 2 Ordner mit jeweils einem Dokument im Verzeichnis "$usrname/$timestamp".

PUT ../document/create/usrname/timestamp
>> Erstellt dann aus den beiden Dokumenten das Enddokument

GET ../document/usrname/timestamp/
>> liefert dann das fertige Dokument


Hat jmd. vielleicht einen Link oder so für HTTPS? Ich schaffe es HTTPS Serverseitig zu konfigurieren. Per Browser kann ich den Webservice dann auch ganz normal aufrufen und er liefert mir das gewünschte Ergebnis. Das Problem liegt aber beim Java-Client. Dort bekomme ich halt den Fehler: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.

Das ist meine Methode
Java:
public static SSLSocketFactory getFactory( File pKeyFile, String pKeyPassword ) throws Exception {
     KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
     KeyStore keyStore = KeyStore.getInstance("PKCS12");

     InputStream keyInput = new FileInputStream(pKeyFile);
     keyStore.load(keyInput, pKeyPassword.toCharArray());
     keyInput.close();

     keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());

     SSLContext context = SSLContext.getInstance("TLS");
     context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

     return context.getSocketFactory();
   }

Und so ist der Aufruf in der main:
Java:
        URL url = new URL("https://localhost:8443/ws/document/save/" + type + "/" + filename);
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(getFactory(new File("cacerts.jks"), "changeit"));
        connection.setDoOutput(true);
        ...
 

Noctarius

Top Contributor
Damit verlierst du aber den "Stateless" Effekt wenn du den Usernamen als State nutzt.

Für HTTPS würde ich einen Apache dem Tomcat vorschalten. Damit ist die Geschwindigkeit meiner Erfahrung nach besser, da der SSL Stack im Apache besser optimiert ist.
 

DakineVester

Mitglied
Ich verstehe den Unterschied nicht. In deinem Beispiel hast du eine ID, die eine Zuordnung zu den Dokumenten ermöglicht. In meinen Beispiel ist die ID quasi durch den Benutzer und die timestamp-Zahl ersetzt. Ist der Knackpunkt, dass man den Benutzernamen "speichert" bzw. verwendet? Im anderen Fall ist es ja die ID die man speichert/verwendet.

Dein Ansatz ist aber rein technisch nicht möglich bzw. nicht sinnvoll. Ich muss zuerst die beiden Dokumente bereitstellen, da hieraus eine Differenz erstellt wird, und die 3 Dokumente (2 Ausgangsdokumente + 1 Enddokument) werden dann in einem PDF zusammengeführt.

Puh, den Apache vor den Tomcat schalten ist für mich wieder was ganz neues. Da muss ich mich dann auch erstmal schlau drüber machen wie das geht usw. Aber das sollte ja trotzdem nichts daran ändern, dass der Client nicht funktioniert. Die Funktionsweise Clientseitig ist doch wahrscheinlich ähnlich/gleich.
 

Noctarius

Top Contributor
Der entscheidende Punkt ist, dass REST URIs als Document Identifiers nutzt. Wenn du den Usernamen nimmst brichst du dieses Konzept :)
 

DakineVester

Mitglied
So, ich habe das ganze nochmal überdacht und bin zu dem Entschluss gekommen, dass ich die Informationen des Benutzernamens gar nicht brauche. Gehe demnach wie folgt vor:

  • ID erzeugen mit timestamp
  • POST /services/document/{id} >> erstes Dokument hochladen
  • POST /services/document/{id} >> zweites Dokument hochladen
  • PUT /services/document/{id} >> Enddokument erstellen
  • GET /services/document/{id} >> Enddokument herunterladen

Ich denke das sollte auch dem REST-Konzept entsprechen.

Zum HTTPS-Problem werde ich morgen noch einen neuen Thread eröffnen, da es ja dann eher auf den Code usw. eingeht und nicht auf die allgemeine Theorie.

Falls jmd noch weitere Vorschläge/Kritik hat, immer her damit. Ansonsten schonmal besten Dank für das bisherige Feedback und so!
 

DakineVester

Mitglied
Ich nochmal ;)

Ich hab mittlerweile den Webservice soweit fertig und es funktioniert auch alles. Allerdings kamen jetzt nochmal fragen zur Sicherheit auf, da laut meinem Kollegen die Authentifizierung mit HTTP Basic Access nicht ausreichend ist. Sein Vorschlag war "WS-Security".

Mein Problem ist jetzt aber, dass ich zwar recht viel zum Thema WS-Security finde, aber das alles hauptsächlich grobe Informationen sind. Und im Zusammenhang mit REST-Webservices finde ich quasi nix.

Kann mir jemand da eventuell gute Links geben oder was dazu schreiben? Ist es möglich und sinnvoll die Authentifizierung des REST-Webservices über WS-Security zu lösen?

Besten Dank schonmal!
 

fax

Mitglied
WS-Security ist ausschließlich für SOAP entworfen. Das würde ich nicht für REST verwenden. WS-Security baut auf XML Security auf. Letzteres wäre evtl. eine Option, wenn ihr mit REST XML Dokumente umherschiebt. Zunächst musst du mal klären, ob du auf verbindungsorientierte oder nachrichtenorientierte Sicherheit setzen willst.

P.S.: Wenn's nur um Authentifizierung geht, die populärsten Methoden sind SSL mit Benutzername/Passwort oder X.509 Zertifikaten oder alternativ OAuth. Letztendlich ist es REST egal, wie du das absicherst, das sind alles Mechanismen, die der Container mehr oder weniger transparent außerhalb von REST implementiert.
 
Zuletzt bearbeitet:

DakineVester

Mitglied
Okay, dann fällt WS-Security also weg, da der Webservice quasi nix mit XML-Dokumenten am Hut hat.

Damit du vllt genauer verstehst, was ich absichern will, eben eine kleine Erklärung:
Es werden zwei PDF-Dokumente an den Webservice geschickt. Der WS verarbeitet die Dokumente dann und liefert auf GET-Anfrage das Ergebnis. Eine verschlüsselte Datenübertragung habe ich mit HTTPS gelöst. Die Authentifizierung ist dazu notwendig, den Webservice vor unbefugter Nutzung zu schützen. Einwand meines Kollegen war: Sobald einer die Session "abhört" kann er ja quasi weitere Anfragen an den WS schicken.

Mein Einwand wäre: Dadurch, dass die Nachrichten ja verschlüsselt sind und man somit den Key bräuchte.

Ich werd mich jetzt nochmal ein wenig mit OAuth beschäftigen ... Besten Dank schonmal!
 

fax

Mitglied
Damit du vllt genauer verstehst, was ich absichern will, eben eine kleine Erklärung:
Es werden zwei PDF-Dokumente an den Webservice geschickt. Der WS verarbeitet die Dokumente dann und liefert auf GET-Anfrage das Ergebnis. Eine verschlüsselte Datenübertragung habe ich mit HTTPS gelöst. Die Authentifizierung ist dazu notwendig, den Webservice vor unbefugter Nutzung zu schützen. Einwand meines Kollegen war: Sobald einer die Session "abhört" kann er ja quasi weitere Anfragen an den WS schicken.
Wie will jemand die Sitzung abhören, wenn sie mit SSL verschlüsselt ist? Gegen Replay Attacken ist SSL abgesichert, sofern man es nicht zerkonfiguriert hat.

Ich werd mich jetzt nochmal ein wenig mit OAuth beschäftigen ... Besten Dank schonmal!
OAuth verwendet man eigentlich nur, wenn man die Credentials eines externen Webdienstes verwenden will, z.B. ein Facebook Benutzer kann sich bei TripIt mit dem Facebook Konto authentifizieren. Im Unternehmensnetz kann man das genauso gut in LDAP oder AD packen und den Webserver davor setzen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Rest und Sicherheit SOA 3
sascha-sphw Statuscode REST Response DELETE SOA 2
B Authentication & Authorization REST API SOA 43
B REST - es gibt eine REST API, wie mache ich nun in JAVA weiter? SOA 8
mrBrown Rest - Bilder mit Metadaten modellieren SOA 24
OnDemand REST Client Aufbau SOA 7
D POST-Request mit Chrome Rest Client wirft Fehler : HTTP Status 415 - Cannot consume content type SOA 3
Shams Was ist ein "Deployment" bei Rest? SOA 1
M HTTP 400 Feher bei REST Web Service durch POST per FormParam SOA 3
M Kann man das Protokoll eines REST (Jersey) bzw. SOAP Web Services manipulieren? SOA 5
P REST POST -> return SOA 4
G WebServices REST SOA 5
H [REST] Deserialisierung eines Object-Feldes SOA 6
J Berechtigungen bei REST SOA 2
G Rest - Session Handling SOA 3
J REST mit java client und php server SOA 22
C REST Webservices, XML Ausgabe und Objektübertragung SOA 2
F REST Service mit Netbeans und MySQL Datenbank SOA 1
M Sicherer REST-Service SOA 2
K Vortrag über REST SOA 5
T Hat AXIS2 noch Zukunft und wie REST implementieren? SOA 6
T Rest Webservice der 2 verschiedene XML Objekte(JaxB) entgegennimmt SOA 10
T Error beim Versuch, einen Webservice zu kontaktieren SOA 4
J SOA WebService JAX-WS Java-Klasse per wsimport generieren lassen SOA 3
K Webservice: 4 counts of IllegalAnnotationExceptions SOA 0
D Zertifikat Authentifizierung am Webservice SOA 0
P JBOSS 7 und Restful Webservice SOA 1
N WebService Ausgabe einer ArrayList SOA 2
N Web Services Client aus externen WebService erstellen SOA 4
I SOAP Webservice Methoden und Parameter auslesen SOA 3
F [WebService] Array von eigenen Objekten SOA 0
P SOAP Webservice mit HTTP Basic Authentifizierung SOA 1
M JAVA Webservice Währungsrechner DRINGEND Hilfe SOA 1
A Up-/ Download von Dateien zu WebService SOA 6
D WebService Technik - Aufwand Änderung des Application Server SOA 3
R Webservice Timeout Konfiguration SOA 3
D SOAP Webservice (SAP) SOA 3
MQue WebService Versionierung SOA 9
L [AXIS2] OutOfMemory Exception bei Übertragung von größerer Datei via Webservice SOA 3
A Funktion mit Map als WebService SOA 4
T Webservice serviceName im Handler ermitteln SOA 3
N Webservice Einbinden wsdl SOA 7
M Edit und Remove über Webservice SOA 3
F Client Problem gegen Webservice SOA 3
P Java Webservice mit JWS Bindingnamen customizen SOA 4
L wie ArrayList an Webservice geben? SOA 3
B Webservice Config / SoapStub: Best Practice SOA 3
S Objektübertragung Fehler über Webservice SOA 10
E Webservice durch Java ansprechen SOA 7
L Webservice HTTPS Netbeans SOA 2
G NullPointerException bei Parameterübergabe an Webservice mittels kSoap2 SOA 2
M Webservice per URL ansprechen SOA 14
M Webservice Client erstellen und XML Request senden SOA 3
T Verwendung von Eclipse Projekten im Axis2 Webservice SOA 8
S Webservice als "CronJob" SOA 4
M Webservice (JaxWS) extern verfügbar machen SOA 5
M Welches WebService Framework ist denn das beste FRAMEWORK? SOA 5
D Webservice fürs Internet sichtbar machen SOA 2
W WebService aus einer HTML-Seite SOA 9
T WebService innerhalb von Seam-Projekt, komplexe Datentypen SOA 6
N JAX-WS WebService und Tomcat 7 SOA 11
E Trennung von Daten und WebService und Wiederverwendung der Daten SOA 2
G WebService, was darf der Client alles sehen SOA 19
M Nutzen des Webservice AWSECommerceService SOA 1
S AXIS2 Webservice: Umgang mit komplexen Datentypen SOA 5
G Webservice Contract first SOA 8
G WebService -> ServletFilter SOA 2
G WebService Concurrency SOA 19
M Fehler beim Veröffentlichen eines Webservice SOA 6
G WebService Types SOA 7
G OpenLigaDB Webservice Client SOA 4
G WebService WSDL SOA 3
A PHP WebService aus Java aufrufen SOA 2
R Proxy WebService erstellen SOA 3
G JPA/ Webservice: Passwort Feld einer Klasse fürs Lesen "verschleiern" SOA 10
G WebService mit wsdl erstellen SOA 4
P WebService SOA 6
H Webservice: BindingProvider SOA 6
D WebService DB abfrage SOA 4
mabe83 EJB Klassen für Webservice nutzen SOA 2
S Webservice-Client-Klasse gibt immer null zurück SOA 3
G WebService mit komplexen Objekten SOA 5
C Problem mit Java Webservice - SOAPBinding.Style - Wrapper class fehlt SOA 1
S Webservice, Vererbung und Netbeans SOA 3
E Lesen der kompletten SOAP als WebService Provider/Server SOA 4
T WebService Authentifizierung SOA 11
mabe83 Suche Hilfe zum Thema Webservice + EJB SOA 3
T WebService erstellen SOA 28
T Krankes Vorhaben: Von VB auf Java Webservice SOA 10
M Webservice RuntimeModelerException? SOA 5
G Webservice mit Java aufrufen SOA 2
G WebService: mehrere methoden mit demselben Namen SOA 4
T einfacher Webservice SOA 3
G Webservice im JBoss: runtime modeler error SOA 3
V webservice von aussen (webbrowser) ansprechen SOA 2
V Webservice, allgemeine Fragen SOA 9
G Alfresco - WebDav oder WebService SOA 2
0 Webservice nutzen (rpc/enc style) SOA 2
R XML verschicken mit Webservice Server Client SOA 2
R Webservice aufrufen mit SOAP Style.DOCUMENT ? SOA 5

Ähnliche Java Themen

Neue Themen


Oben