💻

SpringSecurityとH2コンソールの利用設定

2023/07/26に公開

対象

以下の環境を利用し、SpringWebによるWebアプリケーション開発を行う場合が対象となる。

  • SpringBoot3.X
  • SpringSecurity 6.X
  • H2 Database

H2の利用設定

通常、SpringBootでデータベースにH2を利用する場合は、依存関係としてH2を追加し、アプリケーション設定の記載のみで利用が可能となる。

  • mavenの場合のpom.xml記述
pom.xml
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
  • Gradleの場合のbuild.gradle記述
build.gradle
dependencies {
    ・・・
    // H2データベースの依存関係追加
    runtimeOnly 'com.h2database:h2'
}
  • SpringBootの設定:application.propertiesの場合
application.properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:~/DB名
spring.datasource.username=管理ユーザーID
spring.datasource.password=管理ユーザーパスワード
spring.sql.init.mode=always
spring.h2.console.enabled=true
  • SpringBootの設定:application.ymlの場合
application.yml
spring:
    datasource:
        driver-class-name: org.h2.Driver
        url: jdbc:h2:~/DB名
        username: 管理ユーザーID
        password: 管理ユーザーパスワード
    sql:
        init-mode: always
    h2:
        console:
            enabled: true

しかし、SpringSecurityを追加したアプリケーションの場合は、上記設定のみではH2コンソールのページ(http://localhost:8080/h2-console )にはアクセスができない。

そこで、まずはSpringSecurity側にH2コンソールのページを管理対象とする必要がある。

SpringSecurityの設定

設定クラスの作成とアノテーション付与

まず、SpringSecurity側で設定クラスを作成する。SpringSecurity6では、特に継承やインターフェースを必要とはしないが、アノテーションとして@Configuration@EnableWebSecurityを付与し負ければならない。
今回は設定クラスをSecurityConfigという名前で作成する。

SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

}

セキュリティフィルターの作成

セキュリティ設定クラス内では、セキュリティフィルターをメソッド定義することにより、認証や認可内容を追加することが可能となっている。

セキュリティフィルターを指定するメソッドには、以下の内容が必要となっている。

  1. 戻り値:org.springframework.security.web.SecurityFilterChain
  2. 引数:org.springframework.security.config.annotation.web.builders.HttpSecurity
  3. 例外:Exceptionの送出
  4. DI登録:メソッドへ@Beanアノテーションの付与
SecurityConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.config.Customizer;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain 
        securityFilterChain(HttpSecurity http) throws Exception {
    }
}

SpringWeb管理外URLの設定

まず、/h2-consoleへのパスはSpringSecurityの認証を不要とする設定を行うため、引数のHttpSecurityオブジェクトに対し認可設定(authorizeHttpRequests())を追加する。

また、H2コンソールはSpringMVCの管理外である。(H2Console用のコントローラなどをSpringWeb内で作成することがない)
そのため、requestMatchers()メソッドの引数にはAntPathRequestMatcherを使用する必要がある。

以下が、H2コンソールを認証不要とする設定の例である。

SecurityConfig.java(部分)
@Bean
public SecurityFilterChain 
    securityFilterChain(HttpSecurity http) throws Exception {

    http.authorizeHttpRequests(
         auth -> auth
            .requestMatchers(
               AntPathRequestMatcher.antMatcher("/h2-console/**")).permitAll());
    ・・・
    return http.build();
}

CSRFトークン

H2コンソールではCSRFトークンを生成しないが、SpringSecurityではPOSTメソッドは全てCSRFトークンを必須としている。そのため、H2コンソールではCSRFを利用しないように ignoringRequestMatchersの設定が必要となる。

SecurityConfig.java(部分)
@Bean
public SecurityFilterChain 
    securityFilterChain(HttpSecurity http) throws Exception {
    ・・・
    http.csrf(
         csrf -> csrf
            .ignoringRequestMatchers(
             AntPathRequestMatcher.antMatcher("/h2-console/**")));
    ・・・
    return http.build();
}

セキュリティヘッダー

H2コンソールでは、セキュリティヘッダーが付与されていると使用できなくなる。そのため、H2のパス内ではセキュリティヘッダーを利用不可とする。
(訂正)公式サイトでは自サイトからであれば読み込み可能とする指定を推奨しているようなので、frameOptionのsameOrigin()を使用するよう変更。

SecurityConfig.java(部分)
@Bean
public SecurityFilterChain 
    securityFilterChain(HttpSecurity http) throws Exception {
    ・・・
    http.headers(headers -> headers.frameOptions(
                         frame -> frame.sameOrigin()));
    ・・・
}

セキュリティヘッダーやCSRFトークンの設定など、H2コンソール以外では、利用可能としたい。そのため、最終的にはsecurityMatcher()を使ってエンドポイントの設定などを実施する。

SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher(AntPathRequestMatcher.antMatcher("/h2-console/**"))
                .authorizeHttpRequests(authz -> authz
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/h2-console/**")).permitAll())
                .csrf(csrf -> csrf
                        .ignoringRequestMatchers(AntPathRequestMatcher.antMatcher("/h2-console/**")))
                .headers(headers -> headers.frameOptions(
                         frame -> frame.sameOrigin()))
                .securityMatcher("/**")
                .formLogin(Customizer.withDefaults())
                .csrf(Customizer.withDefaults())
                .headers(Customizer.withDefaults())
                .authorizeHttpRequests(authz -> authz.anyRequest().authenticated());
        return http.build();
    }
}

ソースコードはGitHubにて公開しています。

https://github.com/SakiShiomura/SpringSecurityAndH2

Discussion