Spring Boot 3での認証除外設定
問題概要
Spring Boot 3への移行後、/openapi/openapi.yml
パスへのアクセスを認証対象から除外する設定が機能しなくなる問題が発生します。Spring Boot 2.7.5では正常に動作していた以下の設定が、Spring Boot 3.0.0-RC2/3.0.0では認証免除にならないケースが見られます。
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests((requests) -> requests
.requestMatchers(HttpMethod.OPTIONS).permitAll()
.requestMatchers("/openapi/openapi.yml").permitAll()
.anyRequest().authenticated()
)
.httpBasic();
return http.build();
}
}
根本原因
Spring Boot 3の新しいセキュリティ実装での主な変更点:
WebSecurityConfigurerAdapter
の廃止antMatchers()
からrequestMatchers()
へのメソッド名変更- パスマッチングのロジック変更(Antパスvs完全一致)
特に重要なのがパスマッチング動作の変更です。Spring Boot 3では、文字列で指定したパスが以下のいずれかで解釈されます:
requestMatchers("/path")
: 正確パスマッチを期待requestMatchers("/path/**")
: Antスタイルのワイルドカードが必要
元の問題では /openapi/openapi.yml
のみを指定していますが、Antスタイルのワイルドカードがないため、完全一致のみが許可され、関連するリクエスト(例: /openapi/openapi.yml?version=1
)は除外されません。
解決方法
方法 1: AntPathRequestMatcherを使用する(推奨)
Spring Securityチーム推奨の最も安定した方法です:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(requests -> requests
.requestMatchers(new AntPathRequestMatcher("/openapi/openapi.yml")).permitAll()
.anyRequest().authenticated()
)
.httpBasic();
return http.build();
}
利点
- Antパスパターンを明示的に指定可能
- ワイルドカードや複雑なパスパターンにも対応
- Spring Securityのアップデートで安定
方法 2: 複数SecurityFilterChainを定義
パブリックパスとセキュアパスで別々のフィルターを定義:
@Bean
@Order(1)
public SecurityFilterChain publicFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher("/openapi/openapi.yml")
.csrf().disable()
.authorizeHttpRequests(requests -> requests
.anyRequest().permitAll()
);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain privateFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(requests -> requests
.anyRequest().authenticated()
)
.httpBasic();
return http.build();
}
注意
@Order
アノテーション必須(publicが先に実行される)
方法 3: ホワイトリストで複数パス指定
Swagger UIなどの関連パスを一括管理:
private static final String[] ALLOWED_PATHS = {
"/openapi/openapi.yml",
"/swagger-ui/**",
"/v3/api-docs/**",
"/swagger-resources/**"
};
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(requests -> requests
.requestMatchers(ALLOWED_PATHS).permitAll()
.anyRequest().authenticated()
)
.httpBasic();
return http.build();
}
動作確認済み環境
- Spring Boot 3.0.0 (GA)
- Spring Boot 3.1.1
- Java 17+
ベストプラクティス
- RC版ではなく安定版を使用: RC(リリース候補)版はバグの可能性あり
- ワイルドカード活用:
/openapi/**
で関連リソースをカバー - HTTPメソッド明示:
requestMatchers(HttpMethod.GET, "/path")
- CSRF保護の注意:
csrf().disable()
は公開API向け
トラブルシューティング
設定が機能しない場合の確認ポイント:
- Spring Bootバージョンが3.0.0以上か
@Bean
アノテーションが付いているか- パスの先頭スラッシュ(
/
)が付与されているか - ワイルドカード(
/**
)が適切に設定されているか
結論
Spring Boot 3では、認証除外パス指定方法が以下の点で改善されました:
- コードの宣言的記述への移行
- 型安全な設定の強化
- 複数セキュリティポリシーの柔軟な定義
推奨されるパターンは AntPathRequestMatcher
を利用した明示的パス指定 です。これによりSpring Boot 2.x時代のantMatchers()
と同様の動作が保証され、スムーズな移行が可能です。