Apache SSLプロキシの背後にある専用のアプリサーバーにTomcatが組み込まれたSpring Boot(Spring MVC)アプリがあります。
プロキシサーバーのSSLポートは4433で、appserverのポート8080に転送されます。
したがって、プロキシサーバーへの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
しかし、まだ成功していません。
このソリューションを適用しようとしています: 59.8フロントエンドプロキシサーバーの背後でTomcatを使用
Apacheで mod_proxy を設定し、期待されるヘッダーを送信することを確認しました。
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
にローカルにリダイレクトし続けます。
このシナリオを機能させるために必要なことは他にありますか?
また、プロキシURLの「/ appname」の部分が心配です。アプリサーバーでは、アプリケーションのルートは「/」です。プロキシを経由するときに、クライアントに返送されるすべてのURLに「/ appname」を含めるように、Springにどのように指示する必要がありますか?
先日も同じ問題がありました。 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アプリに指示する必要があります。したがって、application.properties(またはSpring Bootsがプロパティを理解するその他の場所)に次の行を追加します。
server.use-forward-headers=true
これらの2つのことを正しく行うと、アプリケーションが送信するすべてのリダイレクトは、nothttp://127.0.0.1:8080/ [ path] しかし、自動的に https://www.myapp.com/ [path]
Update 1。このトピックに関するドキュメントは here です。少なくともプロパティserver.Tomcat.internal-proxies
信頼できるプロキシサーバーのIPアドレスの範囲を定義します。
プロキシは正常に見えますが、バックエンドアプリもある程度までは正常に動作しますが、RemoteIpValve
の変更されたリクエストが表示されていないようです。 RemoteIpValve
のデフォルトの動作には、(セキュリティチェックとして)プロキシIPアドレスのパターンマッチが含まれ、有効なプロキシからのものと思われるリクエストのみを変更します。パターンは、Spring Bootで10.*.*.*
や192.168.*.*
などの既知の内部IPアドレスのセットにデフォルト設定されるため、プロキシがそれらのいずれかにない場合、明示的に設定する必要があります。
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として知られるバルブを備えています。このValveは、Apache remotip_module のポートです。このValveの主な目的は、「リクエストを開始したユーザーエージェントを発信ユーザーエージェントとして扱う」ことです。これは「認証とログ記録の目的」です。このバルブを使用するには、設定する必要があります。
このバルブの詳細については、こちらをご覧ください こちら 。
Spring Bootは、server.Tomcat.remote_ip_headerおよびserver.Tomcat.protocol_headerプロパティを介してapplication.propertiesを介してこのバルブの設定を便利にサポートします。
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 }
Application.propertiesで:
server.use-forward-headers=true
設定してみましたか
server.context-path=/appname
春のブーツで?
次のような書き換えルールを設定してみてください。 https:// proxyserver:4433/appname >> forward >> http:// appserver:8080/appname
そして、アプリケーションコンテキストを「appname」に設定しますserver.context-path =/appname
ローカルで http:// appserver:8080/appname で実行でき、逆プロキシ経由で https:// proxyserver:4433/appname でアクセスできます
JBOSSを使用しているため、jbossのstandalone.xmの変更:
<http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true" enable-http2="true"/>
Tomcatにも同様の構成があり、Tomcatにプロキシ転送アドレスを尊重するように通知します(proxy-address-forwarding = "true")。