Spring-boot со встроенным Tomcat за прокси Apache
у нас есть приложение spring-boot/spring-mvc со встроенным Tomcat на выделенном appserver за SSL-прокси Apache.
SSL-порт на proxyserver-4433, переадресация на порт 8080 на appserver.
таким образом, URL-адрес прокси-сервера пересылается как:
https://proxyserver:4433/appname >>forward>> http://appserver:8080/
при работе без прокси-сервера первое, что происходит, это
spring-security перенаправляет запрос, например:
http://appserver:8080/ >>redirect>> http://appserver:8080/login
для отображения формы входа, по расширение WebSecurityConfigurerAdapter
С
...
httpSecurity.formLogin().loginPage("/login") ...
...
он отлично работает без прокси, но с прокси-сервером перенаправление необходимо изменить, поэтому Spring следует перенаправить на соответствующий прокси-URL, например:
http://appserver:8080/ >>redirect>> https://proxyserver:4433/appname/login
но пока безуспешно.
Я пытаюсь применить это решение:
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-use-tomcat-behind-a-proxy-server (59.8 использовать Tomcat за передним концом прокси-сервер)
мы настроили mod_proxy в Apache и проверили, что он отправляет ожидаемые заголовки:
X-Forwarded-For: xxx.xxx.xxx.xxx
X-Forwarded-Host: proxyserver
X-Forwarded-Port: 4433
X-Forwarded-Proto: https
приложение запускается с параметрами:
export ARG1='-Dserver.tomcat.protocol-header=x-forwarded-proto'
export ARG2='-Dserver.tomcat.remote-ip-header=x-forwarded-for'
java $ARG1 $ARG2 -jar webapp.jar
все еще перенаправление не работает.
он будет продолжать перенаправлять локально, в http://appserver:8080/login
который недоступен для клиентов.
есть ли что-нибудь еще, что нам нужно сделать, чтобы этот сценарий работал?
редактировать: кроме того, я обеспокоенный частью" / appname " в URL-адресе прокси. На appserver приложение коренится в "/". Как spring следует проинструктировать, что" /appname " должен быть включен во все URL-адреса, отправленные клиентам, при прохождении через прокси-сервер?
6 ответов
у меня была такая же проблема на днях. После некоторой отладки Spring Boot 1.3 я нашел следующее решение.
1. вы должны настроить заголовки на прокси-сервере Apache:
<VirtualHost *:443>
ServerName www.myapp.org
ProxyPass / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPreserveHost On
... (SSL directives omitted for readability)
</VirtualHost>
2. вы должны сказать, что ваше приложение Spring Boot использует эти заголовки. Поэтому поставьте следующую строку в своем заявлении.свойства (или любое другое место, где Spring Boots понимает свойства):
server.use-forward-headers=true
Если вы сделаете эти две вещи правильно, каждое перенаправление вашего приложения отправляет will не на http://127.0.0.1:8080/[путь] но автоматически в https://www.myapp.com / [путь]
обновление 1. документация по этой теме здесь. Вы должны прочитать его, по крайней мере, чтобы быть в курсе свойства server.tomcat.internal-proxies
который определяет диапазон IP-адресов для прокси-серверов, которым можно доверять.
ваш прокси выглядит нормально, и так же бэкэнд приложение, до определенного момента, но он, кажется, не видит RemoteIpValve
измененный запрос. Поведение по умолчанию RemoteIpValve
включает соответствие шаблона для IP-адреса прокси (в качестве проверки безопасности), и он только изменяет запросы, которые он считает от действительного прокси. Шаблон по умолчанию в Spring Boot для известного набора внутренних IP-адресов, таких как 10.*.*.*
и 192.168.*.*
, поэтому, если ваш прокси-сервер не находится на одном из них, вам нужно явно настроить его, например,
server.tomcat.internal-proxies=172\.17\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}
(используя формат файла свойств, что означает, что вам нужно дважды избежать обратных косых черт).
вы можете видеть, что происходит в RemoteIpValve
Если вы устанавливаете
logging.level.org.apache.catalina.valves.RemoteIpValve=DEBUG
или установить точку останова в нем.
типичное решение этой проблемы-позволить прокси-серверу обрабатывать любую необходимую перезапись. Например, в Apache вы можете использовать rewrite_module и/или headers_module для исправления заголовков. В качестве другого примера Nginx обрабатывает этот и другие подобные случаи автоматически после настройки вышестоящих серверов.
в ответ на комментарии:
какова конфигурация весенней загрузки remote_ip_header и protocol_header ценности?
давайте забудем Spring Boot на мгновение. Tomcat, встроенный контейнер сервлетов, имеет клапан, известный как RemoteIpValve. Этот клапан является портом Apache remotip_module. Основная цель этого клапана состоит в том, чтобы рассматривать "useragent, который инициировал запрос, как исходный useragent" для "целей авторизации и регистрации". Для того, чтобы этот клапан использовался, его необходимо настроить.
пожалуйста найдите больше информации о этот клапан здесь.
ботинок весны удобно поддерживает устанавливать этот клапан через применение.свойства через сервер.кот.remote_ip_header и сервер.кот.свойства protocol_header.
у меня был точно такой же случай с использованием haproxy в качестве балансировщика нагрузки с приведенной ниже конфигурацией, которая для меня. Единственное, что клиент IP находится в request.getRemoteAddr()
и не в "X-Forwarded-For"
заголовок
frontend www
bind *:80
bind *:443 ssl crt crt_path
redirect scheme https if !{ ssl_fc }
mode http
default_backend servers
backend servers
mode http
balance roundrobin
option forwardfor
server S1 host1:port1 check
server S2 host2:port2 check
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
в приложение.свойства:
server.use-forward-headers=true
попробуйте установить правило перезаписи, как: https://proxyserver:4433/appname >>вперед>> http://appserver:8080/appname
а затем установите контекст приложения в " appname" сервер.context-path= / appname
таким образом, локально вы можете запустить http://appserver:8080/appname и через обратный прокси вы получаете доступ через https://proxyserver:4433/appname
поскольку я использую JBOSS, изменения в автономном режиме.ХМ из с JBoss:
<http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true" enable-http2="true"/>
Tomcat будет иметь аналогичную конфигурацию, чтобы сообщить Tomcat (proxy-address-forwarding="true") уважать адрес пересылки прокси.