Приложение Spring Boot со встроенным Tomcat за обратным прокси-сервером, не перенаправляющим на https при запросе / contextPath без завершающего слеша - PullRequest
0 голосов
/ 03 июня 2019

Эта проблема, кажется, задавалась несколько раз, но для этого конкретного случая я не нашел правильного решения.

Приложение представляет собой Spring Boot 1.5.x, которое использует встроенный сервер Tomcat и работает в Openshift. Последний имеет Маршрутизатор с маршрутом HTTPS, который завершает туннель TLS и перенаправляет трафик по HTTP в модуль приложения. Кроме того, он вставляет заголовки X-Forwarded-header (включая заголовок X-Forwarded-Proto), чтобы перенаправления приложений создавались с использованием протокола https.

Я настроил server.use-forward-headers: true в приложении Spring Boot и проверил его:

1) OK -> https://ocproute/myapp/ перенаправляет 302 на мою домашнюю страницу, сохраняя протокол https (Tomcat RemoteIpValve позаботился об этом).

2) FAIL -> https://ocproute/myapp (обратите внимание, что косой черты нет) перенаправляет с 302 на http://ocproute/myapp/ Как вы можете видеть, он изменил протокол на http, поскольку RemoteIpValve еще не был вызван) .

Журналы показывают, что Http11InputBuffer Tomcat получает запрос и в какой-то момент перенаправляет его без учета заголовка X-Forwarded-Proto.

Как это можно исправить?

2019-06-03T17:31:59.230 ( -  -  -  -  - ) o.a.t.u.n.NioEndpoint DEBUG - Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1511311d:org.apache.tomcat.util.net.NioChannel@5209052:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:64871]], Read direct from socket: [595]
2019-06-03T17:31:59.230 ( -  -  -  -  - ) o.a.c.h.Http11InputBuffer DEBUG - Received [GET /myapp HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
X-Forwarded-Proto: https
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,es;q=0.7,cy;q=0.6
Cookie: JSESSIONID=4693A1F63CD3E18058F98E129D11CE57

]
...

1 Ответ

0 голосов
/ 05 июля 2019

Чтобы сделать это, мне пришлось отключить перенаправление корневого контекста, настраивая контекст Tomcat:

@Configuration
class TomcatConfiguration : EmbeddedServletContainerCustomizer {

    override fun customize(container: ConfigurableEmbeddedServletContainer) {
        val factory = container as TomcatEmbeddedServletContainerFactory
        factory.tomcatContextCustomizers = listOf(CustomCustomizer())

    }

    class CustomCustomizer : TomcatContextCustomizer {
        override fun customize(context: Context) {
            context.mapperContextRootRedirectEnabled = false
            context.addServletContainerInitializer(WsSci(), null)
        }
    }

}
...