Spring Security 6 でのJWT設定
問題
Spring Security 6.0で既存のJWT設定コードが非推奨になり、エラーが発生するケースが増えています。特に以下の点で問題が発生します:
OAuth2ResourceServerConfigurer::jwt
メソッドの非推奨化antMatchers()
,mvcMatchers()
,regexMatchers()
メソッドの完全削除- 設定方法全体がラムダ式ベースのDSLに移行
典型的なエラー例(非推奨の設定):
java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// ... 他の設定 ...
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); // 非推奨!
return http.build();
}
移行の必要性
Spring Security 5.8では非推奨警告が表示されますが、6.0では完全に動作しなくなります。既存の設定は早期の修正が必要です。
解決策:新しいJWT設定方法
Spring Security 6.xではラムダ式ベースのDSLを使用した設定が必須です。以下のいずれかの方法で実装します。
方法1: デフォルト設定を使用(推奨)
java
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
方法2: カスタムJwtDecoderを設定
java
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtDecoder())));
return http.build();
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder
.withJwkSetUri("https://auth-server-url/.well-known/jwks.json")
.build();
}
設定のポイント
Customizer.withDefaults()
: SpringのデフォルトJWT処理を適用- カスタムDecoderが必要な場合は直接
jwt.decoder()
を実装 requestMatchers()
で新しいエンドポイント指定を追加可能java.authorizeHttpRequests(auth -> auth .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() )
Kotlinでの実装例
kotlin
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http
.authorizeHttpRequests { auth ->
auth
.requestMatchers("/api/**").authenticated()
.anyRequest().permitAll()
}
.oauth2ResourceServer { oauth2 ->
oauth2.jwt(Customizer.withDefaults())
}
return http.build()
}
移行ガイダンス
1. メソッドチェーンからラムダ式へ
非推奨の書き方 | 新しい書き方 |
---|---|
.and() | ラムダ式のネスト化で不要に |
httpBasic() | httpBasic { ... } |
oauth2ResourceServer().jwt() | oauth2ResourceServer { it.jwt { ... } } |
2. エンドポイント指定の変更
java
// 古い書き方 (削除済み)
.antMatchers("/admin/**").hasRole("ADMIN")
// 新しい書き方
.requestMatchers("/admin/**").hasRole("ADMIN")
3. 依存関係の更新
Spring Boot 3.x以上を使用していることを確認:
gradle
// build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.0'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
}
注意点
- Spring Security 5.8→6.0への直接移行は非推奨
- 公式が推奨する移行パス:
- 移行中は公式移行ガイドを参照
ベストプラクティス
- JWTデコーダの外部設定
java
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwksUri;
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(jwksUri).build();
}
- カスタム認証エラー処理
java
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(Customizer.withDefaults())
.authenticationEntryPoint((req, res, ex) -> {
res.sendError(HttpStatus.UNAUTHORIZED.value());
})
)
- プロファイル別設定
java
@Profile("!prod")
@Bean
public SecurityFilterChain localFilterChain(HttpSecurity http) /* ... */
@Profile("prod")
@Bean
public SecurityFilterChain prodFilterChain(HttpSecurity http) /* ... */
これらの設定により、Spring Security 6.xの新アーキテクチャに準拠した安全なJWT認証を実装できます。