こんにちは、サイオステクノロジー技術部の武井です。今回は、Azure Web AppsのSSL化でドハマリした記録を書こうと思います。ちなみに本件、ドハマリした挙句解決してません。その記録だけを書き留めようと思っただけです。
Azure Web Apps(Windows)は内部的に以下のような構成になっているらしいです。
Application Request Routingというリバースプロキシのようなものが、フロントでHTTPS(HTTPでも可)でリクエストを受けて、バックエンドにいるTomcatにhttpsでアクセスしてきます。なのでSSLの終端はApplication Request Routingで行います。
SSLしたかったので、https://〜でアクセスしたところ、途中でHTTPのアクセスになってしまうところがありました。HTTPヘッダ見てみたら、Locationヘッダにhttpsで返していたので、リダイレクトきっかけでHTTPになってしまうようでした。
たしかに、WebアプリケーションはHTTPでリクエストを受けているので、LocationヘッダにHTTPで返すだろうなぁと思いました。
そこで色々調べると、Spring Security(今回、Tomcat上で稼働しているアプリケーションが採用しているセキュリティフレームワーク)で、以下のような設定を入れると、HTTPでアクセスしてきた場合、HTTPSにリダイレクトしてくれるらしいです。こりゃいいとおもいました。
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity https) throws Exception { https.authorizeRequests() .antMatchers("/**").hasRole("USER") .and() .formLogin() .and() .requiresChannel().anyRequest().requiresSecure(); } ・・・
しかしこれではだめでした。リダイレクトループが発生してしまいました。多分、以下のようなことが起こっていると想像できます。
1.https://hoge.com/loginにアクセスします。
2.Application Request RoutingはHTTPに変換して、Tomcat上のWebアプリケーションにフォワードします。
3.Tomcat上のWebアプリケーションは、https://hoge.com/loginにリダイレクトします。正確に言うと、https://hoge.com/loginにリダイレクトするためのLocationヘッダをHTTPレスポンスに乗せます。
4.3のLocationヘッダをブラウザが受け取って、https://hoge.com/loginにリダイレクトする。
5.4のLocationヘッダを受けて、https://hoge.com/loginにアクセスします。
6.Application Request RoutingはHTTPに変換して、Tomcat上のWebアプリケーションにフォワードします。
7.Tomcat上のWebアプリケーションは、https://hoge.com/loginにリダイレクトします。正確に言うと、https://hoge.com/loginにリダイレクトするためのLocationヘッダをHTTPレスポンスに乗せます。
8.3のLocationヘッダをブラウザが受け取って、https://hoge.com/loginにリダイレクトする。
その後は、5に戻って、ひたすら5〜8の無限ループになります。
しかしながら、これを回避する方法があるとWebで見つけました。以下の設定をapplication.propertiesに入れます。
server.tomcat.remote_ip_header=x-forwarded-for server.tomcat.protocol_header=x-forwarded-proto security.require-ssl=true
Application Request Routingは、ブラウザのURLのスキームをx-forwarded-protoというHTTPヘッダに乗せて、Tomcatに送ってくれるらしいです。上記の設定をすることにより、Spring Securityは、ユーザーがHTTPSで接続してきたとき、つまりx-forwarded-protoヘッダの値がhttpsだったときはhttpsにリダイレクトしなくなるらしいのです。
この設定を施したのですが、やっぱり、無限ループになってしまいました。Web上ではこの方法で解決しているひとが多いのですが、なぜか私の環境ではだめでした。なんででしょうか?
困り果てたので、アプリケーションの中でリダイレクトを定義しているところを、全てスキームとFQDNを書くようにしました。つまり、例えば、
https.formLogin() .loginProcessingUrl("/login") .loginPage("/loginForm");
こう書いてたのを
https.formLogin() .loginProcessingUrl("/login") .loginPage("https://contoso.com/loginForm");
としました。めんどくさいですが、今のところ、これしか解決策がないのです。
誰か、教えてください・・・。
Azureポータルで、対象のWebアプリの「拡張機能」メニューから、「Redirect HTTP to HTTPS」拡張機能をインストールしてみて、挙動を試してみてください。
https://www.siteextensions.net/packages/RedirectHttpToHttps/
佐藤様
コメントありがとうございます!!頂きました方法、ぜひ試してみたいと思います。