【Spring Security】Basic認証いらないけど、良い感じにデフォルトのレスポンスヘッダーを使いたい時に見る記事

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を依存関係に追加します。

```gradle:
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認証を無効化します。

```kotlin:WebSecurityConfig.kt
@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 など）を使用するとエラーが返されてしまいます。

なのでその対策をしましょう。

```kotlin:WebSecurityConfig.kt
@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認証を使わないならデフォルトのユーザも必要ないので削除してしまいましょう。

```kotlin:WebSecurityConfig.kt
@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メソッドなどをオーバーライドして上書きする必要があります。

やってること自体はそこまで難しくないので[公式ドキュメント](https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#servlet-headers)を読めばすぐにできると思います。

### 参考文献
[Spring Security Reference(公式ドキュメント)](https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/)
[Property 'security.basic.enabled' is Deprecated: The security auto-configuration is no longer customizable](https://stackoverflow.com/questions/49717573/property-security-basic-enabled-is-deprecated-the-security-auto-configuration)
[Remove “Using default security password” on Spring Boot](https://stackoverflow.com/questions/30761253/remove-using-default-security-password-on-spring-boot)
[Spring Security 4を使ったらハマった](https://qiita.com/NagaokaKenichi/items/292729e9c75a01554ff4)