Spring Security 5.4(Spring Boot 2.4)から不正なURLでのリクエストに任意のステータスコードを返せるようになった

Spring Security 5.4(Spring Boot 2.4)から不正なURLでのリクエストに対して、任意のステータスコードを返せるようになりました。とっても嬉しい!!!

Spring SecurityのHttpFirewall

公式ドキュメント#HttpFirewall に詳しく書いてあるのですが、Spring Securityには ;\などが含まれている不正なURLを弾いてくれるHttpFirewallインターフェースがあります(デフォルトでStrictHttpFirewallクラスが使われる)。

不正なURLだと、RequestRejectedExceptionが投げられます(ソースコード)。

2020-12-26 16:12:54.917 ERROR --- Servlet.service() for servlet [dispatcherServlet] in context with path [/] threw exception
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"

Spring Security 5.3.x(Spring Boot 2.3.x)まで

RequestRejectedExceptionのExceptionHandlerがなくて、ステータスコード500が返されていました。(なんでエラー扱いされないといけないんだと何回思ったことか...)

Spring Security 5.4(Spring Boot 2.4)

RequestRejectedHandlerインターフェースが追加されて、RequestRejectedExceptionをハンドリングできるようになりました(プルリク)。

単に任意のステータスコードを返せばよいだけの場合は、HttpStatusRequestRejectedHandlerクラスをBean登録してください。(デフォルトだと400を返します)

@Bean
public RequestRejectedHandler requestRejectedHandler() {
  return new HttpStatusRequestRejectedHandler();
}

404を返したいんだけど...というときは、コンストラクタで渡してください。

@Bean
public RequestRejectedHandler requestRejectedHandler() {
  return new HttpStatusRequestRejectedHandler(HttpStatus.NOT_FOUND.value());
}