Вот что в итоге сработало для меня.
Прежде всего, я удалил из своего web.xml
весь элемент <security-constraint>
, так как он не нужен для реализованного мною решения.
Я также удалил redirect-socket="https"
из конфигурации <http-listener>
. Это тоже не нужно. Вот как выглядят мои <http-listener>
и <https-listener>
:
<http-listener name="default" socket-binding="http" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
Я думаю, что вышеизложенное именно то, что вы получаете в JBoss EAP 7.1 из коробки, поэтому нет необходимости менять это.
Затем я создал фильтр и добавил его в элемент <filters>
подсистемы undertow :
<rewrite name="http-to-https" redirect="true" target="https://%h:8445%U%q"/>
%h
- имя удаленного хоста
%U
- запрашиваемый путь URL
%q
- строка запроса (автоматически добавляется ?
, если она существует)
Я нашел вышеуказанные коды здесь - Я уверен, что где-то есть более нормативные ссылки, но они, кажется, работают.
Наконец, я добавил ссылку на фильтр вместе с предикатом в элементе <server>/<host>
(также в подсистеме undertow ):
<server name="default-server">
<http-listener name="default" socket-binding="http" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
<filter-ref name="http-to-https" predicate="equals(%p, 8082)"/>
<http-invoker security-realm="ApplicationRealm"/>
</host>
</server>
При указанной выше конфигурации запрос перенаправляется без перекодирования URL:
$ curl -I -L -k http://localhost:8082/get-parameter-test?url=http%3A%2F%2Fwww.google.com
HTTP/1.1 302 Found
Connection: keep-alive
Server: JBoss-EAP/7
Location: https://127.0.0.1:8445/get-parameter-test?url=http%3A%2F%2Fwww.google.com
Content-Length: 0
Date: Tue, 11 Jun 2019 17:43:23 GMT
HTTP/1.1 200 OK
Connection: keep-alive
X-Powered-By: Undertow/1
Server: JBoss-EAP/7
Content-Length: 0
Date: Tue, 11 Jun 2019 17:43:23 GMT
* * 1 042 & hellip; и параметр правильно читается из Java:
url parameter read as: [http://www.google.com]
Нет необходимости устанавливать decode-url="true"
в прослушивателях http / https, поскольку это значение по умолчанию.
NB. Вышеприведенное заставляет JBoss EAP 7.1 отправлять редирект 302. Я понятия не имею, как настроить перенаправление 303 или 307.
Последнее замечание
Очевидная альтернатива вышеприведенному - программно выполнить перенаправление из кода вашего приложения, используя HttpServletRequest # sendRedirect . И в этом случае вам не нужно redirect-socket="https"
в вашем http-listener
.
Очевидно, что атрибут redirect-socket
необходим только в сочетании с элементом <security-constraint>
в web.xml вашего приложения. Это потому, что в противном случае (то есть, если у вас есть <security-constraint>
в вашем web.xml
, но нет redirect-socket
в вашем http-listener
), вы получите:
ERROR [io.undertow.request] (default task-14) UT005001: An exception occurred processing the request: java.lang.IllegalStateException: UT010053: No confidential port is available to redirect the current request.
).
Однако, если у вас есть и <security-constraint>
, и redirect-socket
, строка запроса без необходимости повторно кодируется (и, таким образом, искажается) по URL-адресу в перенаправленном URL-адресе, как описано в вопросе. Так что мне не ясно, какой смысл использовать <security-constraint>
в JBoss EAP 7.1.