2015-05-06 11 views
7

Ich habe eine Spring MVC-Anwendung mit Spring Security gesichert. Der Großteil der Anwendung verwendet einfaches http, um Ressourcen zu sparen, aber ein kleiner Teil verarbeitet mehr vertrauliche Informationen und benötigt einen https-Kanal.Requires HTTPS mit Spring Security hinter einem Reverse-Proxy

Auszug aus den security-config.xml:

<sec:http authentication-manager-ref="authenticationManager" ... > 
    ... 
    <sec:intercept-url pattern="/sec/**" requires-channel="https"/> 
    <sec:intercept-url pattern="/**" requires-channel="http"/> 
</sec:http> 

Alle funktionierte gut, bis wir es an den Hauptserver zu migrieren, entschieden, wo die Anwendungsserver hinter laufen Reverse Proxies. Und da nun HTTPS von den Reverse-Proxys verarbeitet wird, sieht der Anwendungsserver nur HTTP-Anfragen und verbietet den Zugriff auf die /sec/**-Hierarchie.

Nach einigen Recherchen fand ich, dass die Proxys hinzufügen X-Forwarded-Proto: https Header (*), aber in Spring Security HttpServletRequest.isSecure() verwendet wird, um den Kanal Sicherheit angeboten (Auszug aus SecureChannelProcessor javadoc)

Wie kann, um zu bestimmen Ich sage Spring Security, dass ein X-Forwarded-Proto: https Header für eine sichere Anfrage ausreicht?

Ich weiß, ich könnte diesen Teil auf Proxies-Konfiguration melden, aber der Proxies-Administrator mag diese Lösung wirklich nicht, da hinter den Proxies viele Anwendungen stecken und die Konfiguration in einen nicht überschaubaren Zustand wachsen könnte.

Ich benutze derzeit Spring Security 3.2 mit XML-Konfiguration, aber ich bin bereit, Antworten basierend auf Java-Konfiguration und/oder neuere Version zu akzeptieren.

(*) natürlich entfernen die Proxies die Kopfzeile, wenn sie in der eingehenden Anfrage vorhanden war, damit die Anwendung darin sicher sein kann.

+0

Was ist Ihr App-Server? Gibt es dafür keine Einstellung im Tomcat Connector? –

+0

@NeilMcGuigan: Ja, es ist ein Tomcat. Könnte es so einfach sein? –

+0

@NeilMcGuigan: Bitte schreibe es als Antwort, damit ich es annehmen kann. –

Antwort

4

Wenn Ihre Site HTTPS ist und Sie Apache Tomcat hinter einem anderen System ausführen, das die TLS-Beendigung behandelt, können Sie Tomcat anweisen, so zu tun, als handele es sich um die TLS-Beendigung.

Dies macht request.isSecure() zurück true;

Um dies zu tun, müssen Sie zu Ihrer Connector-Konfiguration in server.xml hinzufügen.

https://tomcat.apache.org/tomcat-7.0-doc/config/http.html

Siehe auch das scheme Attribut.

+1

Es ist nicht genau die erwartete Antwort, aber es führte mich auf den richtigen Weg: froh, es zu akzeptieren. –

13

Eine Art von Follow-up zu NeilMcGuigans Antwort, die zeigte, dass die Lösung Servlet Containerseite war.

Tomcat ist noch besser. Es gibt ein Ventil gewidmet Maskierung die Nebenwirkungen eines Reverse-Proxy. Auszug aus Tomcat Dokumentation für Remote IP Valve:

Ein weiteres Merkmal dieses Ventils ist das scheinbare Schema (http/https), Server-Port und request.secure mit dem System durch einen Proxy-Server oder einen Lastausgleicher über einen Anforderungs-Header präsentiert zu ersetzen (zB "X-Forwarded-Proto").

Beispiel der Ventilkonfiguration:

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
    internalProxies="192\.168\.0\.10|192\.168\.0\.11" 
    remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" 
    protocolHeader="x-forwarded-proto" /> 

Auf diese Weise keine anderen Konfiguration der Anwendung selbst, wird der Anruf zu Request.isSecure() true zurück, wenn die Anforderung ein Header-Feld von X-Forwarded-Proto=https enthält.

Ich hatte gedacht, zwei andere Möglichkeiten, aber definitiv prefere, dass man:

  • aktiv einen Filter verwenden, bevor Spring Security ChannelProcessingFilter die Anfrage mit einem HttpServletRequestWrapper zwingende isSecure() wickeln einen X-Forwarded-Proto Header zu verarbeiten - müssen schriftlich und die Filterprüfung und den Wrapper
  • Verwendung eine Feder BeanPostProcessor für ein ChannelProcessingFilter zu suchen und manuell eine ChannelDecisionManager Lage injizieren, um die X-Forwarded-Proto Header zu berücksichtigen - wirklich zu niedrigem Niveau
+1

Ich denke, das sollte die ausgewählte Antwort sein. Definitiv die beste Lösung meiner Meinung nach. Vielen Dank!! – Giordano

+2

@Giordano: Als ich die Frage stelle, war die Antwort, die mir helfen, diese zu finden, Neil's. Das ist der Grund, warum ich es akzeptiert habe :-) - aber da es nicht so komplett war, wie ich es wollte, habe ich dieses hinzugefügt. –

+0

Macht perfekten Sinn, danke für das Teilen dieser zusätzlichen Informationen, die Sie gefunden haben ^^ – Giordano