オブジェクト指向とかデザインパターンとか開発プロセスとかツールとか

satoshi's ソフトウェア開発

js






当サイトはアフィリエイト広告を利用してます。

GAE Java Security Spring Boot

Google App EngineのSpring bootでhttpをhttpsにリダイレクトするには

更新日:


GAE/Javaにアプリケーションをデプロイして、独自ドメインも割り当てて、動かしてみたのです。

とりあえず動くのですが、httpsではないので、Chromeが「保護されていません」と文句を言います。

なので、http接続だったらhttpsにリダイレクトしたかったのです。

Spring Securityを有効化する

Spring Securityを有効化するとデフォルトでhttpをhttpsにリダイレクトするらしいです。
当然ですが、Spring Security は有効化しているつもりです。
もしかして、これだけじゃ有効化できてなかったりします???

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
	</dependency>

そもそも、Http Strict Transport Securityはデフォルトで有効化されていると、Spring Securityのドキュメントに書かれているのに、
サイトにアクセスしてもStrict Transport Securityヘッダーが存在しないんですよね。
pom.xmlに上記のdependencyを追加するだけではStrict Transport Securityヘッダーが追加されないんでしょうか?

なぜなのか。

app.yamlで設定する

で、「app engine http https redirect」ぐぐったら、一番たくさんでてきるのが、app.yamlでの設定です。

https://cloud.google.com/appengine/docs/standard/reference/app-yaml?hl=ja&tab=java

src/main/appengine/app.yaml

handlers:
- url: /.*
  secure: always
  script: auto

やってみたんですが、デプロイでエラーになりました。

ERROR: (gcloud.app.deploy) INVALID_ARGUMENT: WEB-INF/appengine-web.xml is required for this runtime.

appengine-web.xml を作ってデプロイしなおしたら、「404 not found」エラーです。

なぜなのか。

なんとなく、appengine-web.xmlを設置すると、web.xmlを参照して、URLとサーブレットの対応で処理してるっぽい動きです。
Spring BootなのでアノテーションでURLとコントローラーのメソッドを対応付けていますが、それが全部無視されてしまってる?

SecurityConfigでStrict Transport Securityヘッダーを設定する

Spring Securityの公式ドキュメントにしたがって、Strict Transport Securityヘッダーを付加するコードを追加してみました。

https://docs.spring.io/spring-security/site/docs/5.3.9.RELEASE/reference/html5/#headers-hsts

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.headers(
            headers -> 
            headers
            .httpStrictTransportSecurity(
                hsts -> 
                hsts
                .includeSubDomains(false)
                .maxAgeInSeconds(31536000)
                .preload(true)));
        return http.build();
    }
}

公式ドキュメントに書いてあるとおりにやってみたんですが、Strict Transport Securityヘッダーは追加されてません。

なぜなのか。

別の方法をぐぐってみます。

web.xmlでStrict Transport Securityヘッダーを設定する

web.xmlファイルでそれを指定する方法もあるみたいです。

https://stackoverflow.com/questions/63851254/spring-boot-application-http-to-https-redirect-in-google-app-engine

<?xml version="1.0" encoding="utf-8"?>                                                                                                                                                                                    
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"                                                                                                                                                                                    
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                                                                                                                                                                         
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                                                                                                                                                                        
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"                                                                                                                                                       
                             version="3.1">                                                                                                                                                                                            
  <security-constraint>                                                                                                                                                                                                                
    <web-resource-collection>                                                                                                                                                                                                          
      <web-resource-name>HTTPS Redirect</web-resource-name>                                                                                                                                                                            
      <url-pattern>/*</url-pattern>                                                                                                                                                                                                    
    </web-resource-collection>                                                                                                                                                                                                         
    <user-data-constraint>                                                                                                                                                                                                             
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>                                                                                                                                                                          
    </user-data-constraint>                                                                                                                                                                                                            
  </security-constraint>                                                                                                                                                                                                               
</web-app>

やってみたけど、何も変わらないんですよね。

Strict Transport Securityヘッダーを設定する

Spring Securityの公式ドキュメントには、以下の方法も書かれてます
Strict Transport Securityヘッダーを追加する方法です。

公式ドキュメントに掲載されているこのコードを追加してみたら、HTTPSにリダイレクトされました!!

そして、ERR_TOO_MANY_REDIRECTSが発生。

なぜかのか。

https://spring.pleiades.io/spring-security/reference/servlet/exploits/http.html

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // ...
            .requiresChannel(channel -> channel
                .anyRequest().requiresSecure()
            );
        return http.build();
    }
}

解決

シンプルに考えてみることにしました。

要するに、Strict Transport Securityヘッダーが付けばいいんだから、普通の手順でヘッダーを追加すればいいのでは?

https://www.techiedelight.com/ja/add-custom-header-to-all-responses-spring-boot/

@Component
public class HstsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        response.addHeader("Strict-Transport-Security", "max-age=31536000");
        filterChain.doFilter(request, response);
    }
}

これで、いい感じに動いてくれました。

ていうか、Spring Securityの公式ドキュメントが信用できないってどうよ。
なにか大切なことを読み落としてる可能性はあるんだけど。







-GAE, Java, Security, Spring Boot
-, , , ,

Copyright© satoshi's ソフトウェア開発 , 2024 All Rights Reserved Powered by STINGER.