Datei-Upload in Struts2 zusammen mit dem Spring CSRF-Token

8

Ich benutze,

  • Spring Framework 4.0.0 RELEASE (GA)
  • Spring Security 3.2.0 RELEASE (GA)
  • Struts 2.3.16

In dem verwende ich ein eingebautes Sicherheits-Token gegen CSRF-Angriffe.

%Vor%

Es handelt sich um eine mehrteilige Anforderung, bei der das CSRF-Token für die Spring-Sicherheit nicht verfügbar ist, es sei denn, MultipartFilter zusammen mit MultipartResolver ist ordnungsgemäß konfiguriert, sodass die mehrteilige Anforderung von Spring verarbeitet wird.

MultipartFilter in web.xml ist wie folgt konfiguriert.

%Vor%

Und in applicationContext.xml , MultipartResolver wird wie folgt registriert:

%Vor%

Das CSRF-Token wird nun von der Spring-Sicherheit empfangen, aber in Struts tritt ein anderes Problem auf.

Hochgeladene Datei (en) ist jetzt null in Struts Aktionsklassen wie folgt.

%Vor%

Dies geschieht, weil die mehrteilige Anfrage bereits von Spring verarbeitet und konsumiert wird. Daher ist es für Struts nicht als mehrteilige Anfrage und daher als Dateiobjekt in einer Struts-Aktionsklasse verfügbar ist null .

Gibt es eine Möglichkeit, diese Situation zu umgehen? Ansonsten habe ich jetzt mit der einzigen Option, das Token an eine URL als Abfrage-String-Parameter, die sehr zu empfehlen ist und nicht empfohlen wird, verlassen.

%Vor%

Lange Rede, kurzer Sinn: Wie erhalte ich Dateien in einer Struts-Action-Klasse, wenn Spring eine mehrteilige Anfrage bearbeitet? Wenn Spring andererseits nicht ist, um eine mehrteilige Anforderung zu verarbeiten, wird das Sicherheitstoken durchsucht. Wie kann man diese Situation überwinden?

    
Tiny 03.02.2014, 17:32
quelle

4 Antworten

8

Es scheint Ihre beste Wette zu sein, eine benutzerdefinierte MultiPartRequest-Implementierung , die an Spring's MultipartRequest delegiert. Hier ist eine Beispielimplementierung:

sample / SpringMultipartParser.java

%Vor%

Als nächstes müssen Sie sicherstellen, dass Struts es verwendet. Sie können dies in Ihrer struts.xml-Datei wie folgt tun:

struts.xml

%Vor%

WARNUNG : Es muss unbedingt sichergestellt werden, dass eine neue Instanz von MultipartRequest für jede mehrteilige Anfrage erstellt wird, indem der Bereich der Bean richtig festgelegt wird. Andernfalls werden die Race-Bedingungen angezeigt.

Danach werden Ihre Struts-Aktionen die Dateiinformationen wie zuvor hinzugefügt. Beachten Sie, dass die Validierung der Datei (z. B. Dateigröße) jetzt mit filterMultipartResolver statt Struts erfolgt.

Verwenden von Designs zum automatischen Einschließen des CSRF-Tokens

Sie könnten ein benutzerdefiniertes Design erstellen, damit Sie das CSRF-Token automatisch in Formulare einschließen können. Weitere Informationen dazu finden Sie unter Ссылка

Komplettes Beispiel für Github

Sie finden ein vollständiges funktionierendes Beispiel auf GitHub unter Ссылка

    
Rob Winch 12.02.2014, 22:35
quelle
4

Die Formularcodierung multipart/formdata ist für Datei-Upload-Szenarien vorgesehen, dies entspricht der W3C-Dokumentation :

  

Der Inhaltstyp "multipart / form-data" sollte zum Einreichen verwendet werden   Formulare, die Dateien, Nicht-ASCII-Daten und Binärdaten enthalten.

Die Klasse MultipartResolver erwartet nur einen Dateiupload und keine anderen Formularfelder, dies stammt vom Javadoc:

%Vor%

Aus diesem Grund funktioniert das Hinzufügen des CSRF als Formularfeld nicht. Die übliche Methode zum Sichern von Dateiübertragungsanforderungen gegen CSRF-Angriffe besteht darin, das CSRF-Token in einem HTTP-Anforderungsheader anstelle des POST-Hauptteils zu senden. Dafür musst du es zu einem Ajax POST machen.

Für einen normalen POST gibt es keine Möglichkeit dies zu tun, siehe Antwort . Machen Sie den POST entweder zu einer Ajax-Anfrage und fügen Sie den Header mit etwas Javascript hinzu, oder senden Sie das CSRF-Token als URL-Parameter, wie Sie bereits erwähnt haben.

Wenn das CSRF-Token häufig neu generiert wird, wie es idealerweise zwischen Anforderungen sein sollte, dann ist das Senden als Anforderungsparameter weniger problematisch und könnte akzeptabel sein.

Auf der Serverseite müssen Sie die CSRF-Lösung so konfigurieren, dass sie das Token aus dem Header liest. Dies wird normalerweise von der verwendeten CSRF-Lösung erwartet.

    
Angular University 09.02.2014 16:24
quelle
1

Auf den ersten Blick sieht Ihre Konfiguration für mich korrekt aus. Ich denke daher, dass das Problem irgendwo ein kleines bisschen Fehlkonfiguration sein könnte.

Ich hatte ein ähnliches Problem mit Spring MVC anstelle von Struts, das ich mit Hilfe des Spring Security-Teams lösen konnte. Für vollständige Details siehe diese Antwort .

Sie können Ihre Einrichtung auch mit einem funktionierenden Beispiel vergleichen, das auf Github zur Verfügung steht. Ich habe dies auf Tomcat 7, JBoss AS 7, Jetty und Weblogic getestet.

Wenn diese nicht funktionieren, ist es hilfreich, wenn Sie eine einzelne Anwendung mit einer einzelnen Seite mit Ihrer Konfiguration erstellen können, die das Problem demonstriert und sie irgendwo hochladen.

    
manish 10.02.2014 03:21
quelle
1

Ich bin kein Struts-Benutzer, aber ich denke, dass Sie die Tatsache nutzen können, dass Spring MultipartFilter die Anfrage in MultipartHttpServletRequest umschließt.

Bekommen Sie zuerst das HttpServletRequest , in Struts denke ich, dass Sie es so etwas tun können:

%Vor%

Dann retreive die MultipartRequest davon, wickeln Wrapper bei Bedarf:

%Vor%

Wenn diese Anfrage ein Multipart war, besorgen Sie sich die Datei durch den Namen der Formulareingabe:

%Vor%     
holmis83 10.02.2014 09:17
quelle