Перенаправление с http на https - бесконечный цикл

Я работаю над веб-приложением Java, размещенным на сервере Tomcat. Мне нужно настроить перенаправление с www на не-www и с http на https. Мне нужны следующие три URL:

перенаправить на

Для этого я использую UrlRewriteFilter версии 4.0.3 от tuckey.org. Вот мой файл urlrewrite.xml:

<?xml version = "1.0" encoding = "UTF-8"?> 
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd"> 
<urlrewrite> 
  <rule> 
    <name>Redirect www to non-www and http to https</name> 
    <condition type = "request-url" operator = "equal">(^http://example.com|^http://www.example.com|^https://www.example.com)</condition> 
    <from>^(.*)$</from> 
    <to type = "permanent-redirect" last = "true">https://example.com$1</to> 
  </rule> 
</urlrewrite> 

Перенаправления работают, но веб-сайт не загружается, а в браузере отображается сообщение:

This page isn’t working
example.com redirected you too many times.

Я использовал средство проверки перенаправления и обнаружил, что после первоначального перенаправления на https://example.com/ следует еще одно перенаправление на https://example.com/, а затем еще одно и так далее - URL-адрес перенаправляется на себя. Я не понимаю, что порождает этот бесконечный цикл. Любая помощь будет оценена по достоинству!

Обновление: у меня пока нет решения. Если я удалю первый URL из элемента условия, два других перенаправления будут работать, и все будет в порядке, но вопрос в том, как настроить перенаправление из http://example.com.

Я попробовал другой подход - настроить перенаправление на https в файле web.xml, вставив следующий код:

<security-constraint> 
  <web-resource-collection> 
    <web-resource-name>all</web-resource-name> 
    <url-pattern>/*</url-pattern> 
  </web-resource-collection> 
  <user-data-constraint> 
    <transport-guarantee>CONFIDENTIAL</transport-guarantee> 
  </user-data-constraint> 
</security-constraint> 

Результат тот же - https://example.com перенаправляет на себя в бесконечном цикле. Единственная разница в этом случае заключается в том, что перенаправления имеют код состояния 302. Есть идеи о том, что вызывает эту проблему и как ее решить?

Обновление: вот результат выполнения команды curl при использовании UrlRewriteFilter:


Результаты запуска: curl http://example.com

Заголовок ответа

HTTP/1.1 301 Moved Permanently   
Server: nginx admin   
Date: Fri, 04 May 2018 13:24:16 GMT   
Content-Type: text/plain   
Content-Length: 0   
Connection: keep-alive   
Location: https://example.com/   
X-Cache: HIT from Backend  

Результаты запуска: curl https://example.com/

Заголовок ответа

HTTP/1.1 301 Moved Permanently   
Date: Fri, 04 May 2018 11:58:51 GMT   
Server: Apache-Coyote/1.1  
Location: https://example.com/   
Content-Length: 0   
Content-Type: text/plain

Можете ли вы установить условие на (псевдо): (ifNotStartsWith (https) | ^ example.com) Не уверен в синтаксисе (регулярное выражение?) Здесь, но в любом случае, если URL-адрес не HTTPS, вы всегда хотели бы перенаправить, верно?

Jokkeri 30.04.2018 08:28

@Jokkeri Да, я уже пробовал <condition type = "scheme" operator = "equal">^http$</condition> и <condition type = "scheme" operator = "notequal">^https$</condition>. Это тоже не работает.

Rick77 30.04.2018 10:37

Не уверен, что побег будет иметь значение, но попробуйте что-нибудь вроде этого: ^(http://example.com(.*)|http://www.example.com(.*)|http‌​s://www.example.co‌​m(.*))

Jokkeri 30.04.2018 11:33

Посмотрим, поможет ли эта ветка stackoverflow.com/questions/44953464/…

Tarun Lalwani 02.05.2018 18:21

@ Rick77 Судя по вашим примерам curl, у вас запущен nginx. Это правильно? Определить схему может быть сложнее, потому что nginx подключается к Tomcat через простой HTTP - см. этот ответ. Это объясняет, почему удаление первого URL-адреса из вашего условия работает нормально (для example.com больше нет правила). Посмотрите на другой ответ тот же вопрос, который может дать вам подсказку, как применить настраиваемый заголовок, который вы могли бы использовать для определения схемы. Или вы можете обработать перенаправление в nginx.

Franz Fellner 05.05.2018 20:32

@FranzFellner Спасибо за ваш комментарий, это очень полезно. В моем случае заголовок x-forwarded-proto не установлен, и у меня нет доступа к nginx на производственном сервере. Поэтому мне придется попросить хостинг-провайдера выполнить настройку.

Rick77 09.05.2018 14:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
6
1 679
3

Ответы 3

Я бы упростил правило, как показано ниже

<rule>
   <name>Ensure HTTPS</name>
   <condition type = "scheme" operator = "notequal" next = "or">https</condition>
   <condition name = "host" operator = "notequal">www.example.com</condition>
   <from>^/(.*)$</from>
   <to type = "redirect">https://example.com/$1</to>
</rule>

Также убедитесь, что сертификат действителен для example.com, а также указан в потоке ниже.

UrlRewriteFilter: перенаправление www и https

Правило выглядит лучше написанным таким образом, но это не решает проблемы. Сертификат действителен как для example.com, так и для www.example.com.

Rick77 03.05.2018 10:48

Можете ли вы добавить к своему вопросу вывод curl -v https://example.com/? Также подключаетесь напрямую к серверу или к любому другому веб-серверу между ними?

Tarun Lalwani 03.05.2018 10:49

Мои знания о curl могут быть немного устаревшими, но я подумал, что вам нужно выполнить curl -L url, чтобы следовать перенаправлениям.

Кроме того, вы уверены, что проблема не в вашем клиенте?

У меня не установлен curl, и я использую онлайн-инструмент для его запуска. Так что проблема не в моем клиенте. Если я запускаю curl –L http://example.com, я получаю сообщение об ошибке (я думаю, из-за бесконечного цикла перенаправления).

Rick77 08.05.2018 11:56

Кажется, ответ от https://example.com всегда имеет заголовки ниже:

Location: https.example.com
response Code: 301

Действия и перенаправление - это поведение браузера. Возможно, вам потребуется найти способ удалить эти заголовки. Надеюсь, это поможет в какой-то степени.

Другие вопросы по теме