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

Spring Boot Filter无法获取自定义请求头问题求助

问题解决:Spring Filter中无法获取自定义请求头userId

核心原因分析

  1. CORS预检请求干扰:浏览器发送CORS跨域请求时,会先发送OPTIONS预检请求,这个请求不会携带自定义的userId头,如果你看到的日志是预检请求的,自然找不到该字段;而实际业务请求(GET)会携带,但可能你没区分两种请求的日志。
  2. Filter执行顺序问题:如果自定义Filter在Spring内置的CORS Filter之前执行,可能在CORS处理完成前无法获取到自定义头。
  3. 客户端无效头配置:客户端设置了Access-Control-Allow-Origin(这是服务端响应头,客户端无需设置),可能导致请求头处理异常。

具体解决方案

1. 修正Filter代码,区分请求类型并传递正确请求对象

添加请求方法打印,明确区分预检请求和业务请求,同时确保包装后的请求对象进入过滤链:

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
    // 打印请求方法,区分OPTIONS预检和实际业务请求
    System.out.println("当前请求方法:" + httpRequest.getMethod());
    
    Enumeration<String> headerNames = httpRequest.getHeaderNames();
    if (headerNames != null) {
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            System.out.println("Header: " + name + " value:" + httpRequest.getHeader(name));
        }
    }

    // 使用包装后的请求继续执行过滤链
    AuthRequestWrapper authRequestWrapper = new AuthRequestWrapper(httpRequest);
    filterChain.doFilter(authRequestWrapper, servletResponse);
}

2. 全局配置CORS,明确允许自定义头

在Spring中配置全局CORS规则,确保userId被允许传递:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8080")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("Content-Type", "userId") // 明确放行自定义头
                .allowCredentials(false); // 匹配客户端的credentials: "omit"
    }
}

如果使用Spring Security,需要在Security配置中同步开启CORS:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors(cors -> cors.configurationSource(corsConfigurationSource()))
            // 其他安全配置...
            ;
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:8080"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("Content-Type", "userId"));
        configuration.setAllowCredentials(false);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

3. 修正客户端请求代码,移除无效响应头

客户端无需设置Access-Control-Allow-Origin(这是服务端返回给浏览器的响应头),移除后避免请求异常:

let headers: HeadersInit = {
    "Content-Type": "application/json",
    "userId":"ABCD" // 仅保留必要的请求头
}

4. 调整Filter执行顺序

确保自定义Filter在Spring CORS Filter之后执行,通过@Order注解指定优先级:

@Component
@Order(Ordered.LOWEST_PRECEDENCE - 10) // 内置CORS Filter默认优先级为LOWEST_PRECEDENCE,设置比它高的优先级
public class AuthFilter implements Filter {
    // Filter实现代码...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:40:25