Spring Securityを導入しただけで設定されるデフォルトのレスポンスヘッダーをご存知でしょうか?
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
これがお手軽で結構便利なのですが、いざ使おうとSpring Securityを導入すると自動でBasic認証機能が有効になってしまい、別の認証機能を使っていたりそもそも認証が必要ないAPIではむしろ邪魔になってしまいます。
Spring 2.0以前はapplication.properties
でsecurity.basic.enabled = false
とするだけでBasic認証を無効に設定することができたらしいのですが、現在は一手間加える必要があります。
今回はその方法を記事にしました。
Basic認証を無効化する
まずはSpring Securityを依存関係に追加します。
implementation("org.springframework.boot:spring-boot-starter-security:2.2.5.RELEASE")
この状態で任意のAPIを叩くと以下のようにBasic認証に失敗したというレスポンスが返ってきてしまいます。
{
"timestamp": "2020-03-05T00:18:51+09:00",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/api/v1/hogehoge"
}
そこで以下のようなクラスを作成して、Basic認証を無効化します。
@Configuration
@EnableWebSecurity
class WebSecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity?) {
// Basic認証を無効化する。
http?.authorizeRequests()?.anyRequest()?.permitAll()
}
}
これだけでBasic認証が無効化され、レスポンスにSpring Securityのデフォルトのヘッダーが追加されるようになりました。
CSRFを無効化する
Spring SecurityではCSRFがデフォルトで有効化されています。
つまりこのままだと何が起こるかというと、GET以外のHTTPメソッド(POST, PUT, DELETE, PATCH など)を使用するとエラーが返されてしまいます。
なのでその対策をしましょう。
@Configuration
@EnableWebSecurity
class WebSecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity?) {
http?.authorizeRequests()?.anyRequest()?.permitAll()
// CSRFを無効化する。
http.csrf().disable()
}
}
こうすることでCSRFが無効化され、POSTやPUTなどのメソッドでも正常に動作することができます。
Basic認証のデフォルトユーザを削除する
これだけでも良いのですが、このままだとSpringを起動した時に以下のようなデフォルトユーザのBasic認証のパスワードがログに表示されてしまいます。
Using generated security password: d86b4dbb-c7d7-4029-ac1e-53c240eddb60
Basic認証を使わないならデフォルトのユーザも必要ないので削除してしまいましょう。
@Configuration
@EnableWebSecurity
class WebSecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity?) {
http?.authorizeRequests()?.anyRequest()?.permitAll()
http.csrf().disable()
}
override fun configure(auth: AuthenticationManagerBuilder?) {
// デフォルトのユーザを削除してログに表示されないようにする
auth?.inMemoryAuthentication()
}
}
同じconfigureメソッドをオーバーライドするのですが引数が異なるので注意しましょう。
おまけ
レスポンスヘッダの値を変更するのもSpring 2.0以前はapplication.properties
の値を変更するだけで良かったのですが、現在は上記のWebSecurityConfigurerAdapterクラスのconfigureメソッドなどをオーバーライドして上書きする必要があります。
やってること自体はそこまで難しくないので公式ドキュメントを読めばすぐにできると思います。
参考文献
Spring Security Reference(公式ドキュメント)
Property 'security.basic.enabled' is Deprecated: The security auto-configuration is no longer customizable
Remove “Using default security password” on Spring Boot
Spring Security 4を使ったらハマった