You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot API双认证(API KEY+JWT)突然失效求助

问题分析与解决方案

你的问题核心在于多个SecurityFilterChain的匹配逻辑冲突:第一个API KEY过滤器链未限定处理范围,导致所有请求都被其拦截,而该链仅验证API KEY,直接导致JWT请求全部失败。结合你的代码,以下是具体修正方案:

问题代码的核心问题

  1. 内外层类重复添加@EnableWebSecurity注解,引发Spring Security配置加载混乱
  2. API KEY过滤器链未限定处理路径,所有请求都会进入该链验证API KEY,JWT请求自然无法通过
  3. 重复定义AuthenticationManager Bean,无意义且可能引发配置冲突

修正后的代码

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();
        }

    }

}

关键修正点说明

  1. 移除内部类的@EnableWebSecurity:仅保留最外层类的该注解,避免重复加载配置
  2. 为API KEY过滤器链添加requestMatcher:明确该链只处理/api/key/**路径的请求,其他请求自动进入JWT过滤器链
  3. 合并AuthenticationManager Bean:只保留一个全局的AuthenticationManager,消除配置冲突
  4. 调整API KEY链的授权规则:结合requestMatcher使用anyRequest().authenticated(),确保路径匹配精度

额外排查建议

若调整后仍有问题,检查:

  • KeySecurityFilter是否在验证失败时直接终止请求,而非让请求继续流转到下一个链
  • 确认TokenSecurityFilter逻辑正常,比如token解析、认证信息设置是否正确
  • 清理项目target目录后重新编译启动,避免缓存导致配置未生效

内容的提问来源于stack exchange,提问作者Gustavo Rutiquewiski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 13:45:55