Spring Boot API双认证(API KEY+JWT)突然失效求助
问题分析与解决方案
你的问题核心在于多个SecurityFilterChain的匹配逻辑冲突:第一个API KEY过滤器链未限定处理范围,导致所有请求都被其拦截,而该链仅验证API KEY,直接导致JWT请求全部失败。结合你的代码,以下是具体修正方案:
问题代码的核心问题
- 内外层类重复添加
@EnableWebSecurity注解,引发Spring Security配置加载混乱 - API KEY过滤器链未限定处理路径,所有请求都会进入该链验证API KEY,JWT请求自然无法通过
- 重复定义
AuthenticationManagerBean,无意义且可能引发配置冲突
修正后的代码
SecurityConfiguration.java
import br.rutiquewiski.HealthBridge.infra.security.configuration.api_key.KeySecurityFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity public class SecurityConfiguration { @Configuration @Order(1) public static class ApiKeySecurityConfiguration { @Autowired private KeySecurityFilter keySecurityFilter; @Bean public SecurityFilterChain apiKeySecurityFilterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 明确该链仅处理/api/key/**路径的请求 .requestMatcher(new AntPathRequestMatcher("/api/key/**")) .authorizeHttpRequests(auth -> { auth.requestMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**").permitAll(); auth.anyRequest().authenticated(); }) .addFilterBefore(keySecurityFilter, UsernamePasswordAuthenticationFilter.class) .build(); } } @Configuration @Order(2) public static class StandardSecurityConfiguration { @Autowired private TokenSecurityFilter tokenSecurityFilter; @Bean public SecurityFilterChain tokenSecurityFilterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity.csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> { auth.requestMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**").permitAll(); auth.anyRequest().authenticated(); }) .addFilterBefore(tokenSecurityFilter, UsernamePasswordAuthenticationFilter.class) .build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } } }
关键修正点说明
- 移除内部类的@EnableWebSecurity:仅保留最外层类的该注解,避免重复加载配置
- 为API KEY过滤器链添加requestMatcher:明确该链只处理
/api/key/**路径的请求,其他请求自动进入JWT过滤器链 - 合并AuthenticationManager Bean:只保留一个全局的AuthenticationManager,消除配置冲突
- 调整API KEY链的授权规则:结合requestMatcher使用
anyRequest().authenticated(),确保路径匹配精度
额外排查建议
若调整后仍有问题,检查:
KeySecurityFilter是否在验证失败时直接终止请求,而非让请求继续流转到下一个链- 确认
TokenSecurityFilter逻辑正常,比如token解析、认证信息设置是否正确 - 清理项目target目录后重新编译启动,避免缓存导致配置未生效
内容的提问来源于stack exchange,提问作者Gustavo Rutiquewiski
相关产品推荐
相关产品推荐

