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

Spring Security:非跨域OPTIONS请求绕过认证的推荐方式

解决非跨域OPTIONS请求绕过Spring Security认证的标准方案

我完全get你的痛点——CorsFilter确实是专门为跨域预检请求设计的,它会检查Origin这类CORS专属头,对不带这些头的非跨域OPTIONS请求根本不会特殊处理,但实际场景里OPTIONS的用法远不止浏览器预检:比如同域JS的OPTIONS调用、服务器存活检查(ping接口)这些场景,都需要让这类请求绕过认证。

下面是几种Spring生态里推荐的标准方案,完全贴合Spring Security的设计逻辑,不用自己瞎写过滤器:


1. 全局放行所有OPTIONS请求(最直接)

如果你的场景允许所有OPTIONS请求都跳过认证,直接在Spring Security的配置里添加规则即可,这是最简单通用的方式:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // 放行所有HTTP OPTIONS方法的请求
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                // 其他请求必须认证
                .anyRequest().authenticated()
            )
            // 根据你的实际需求添加其他配置,比如JWT认证、表单登录等
            .csrf(csrf -> csrf.disable()); // 如果是API场景,通常需要关闭CSRF

        return http.build();
    }
}

这个配置会让Spring Security直接跳过所有OPTIONS请求的认证流程,不管它是不是跨域的,完美覆盖你说的存活检查、同域JS调用这类场景。


2. 细粒度放行特定路径的OPTIONS请求

如果不想全局放行,只想让某些特定路径(比如健康检查接口/api/health)的OPTIONS请求绕过认证,可以更精准地配置requestMatchers:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // 只放行/api/health路径下的OPTIONS请求
                .requestMatchers(HttpMethod.OPTIONS, "/api/health/**").permitAll()
                // 其他请求必须认证
                .anyRequest().authenticated()
            )
            .csrf(csrf -> csrf.disable());

        return http.build();
    }
}

甚至可以自定义匹配规则,比如结合请求头(非CORS头)来判断:

.requestMatchers(request -> 
    HttpMethod.OPTIONS.matches(request.getMethod()) &&
    request.getHeader("X-Check-Type").equals("health")
).permitAll()

3. 控制器层面单独配置(适合特定端点)

如果某个控制器的OPTIONS请求需要单独处理,也可以直接在控制器方法上标注权限规则:

@RestController
@RequestMapping("/api/health")
public class HealthCheckController {

    // 专门处理OPTIONS请求,允许所有访问
    @RequestMapping(method = RequestMethod.OPTIONS)
    @PreAuthorize("permitAll()")
    public ResponseEntity<Void> handleOptionsRequest() {
        // 可以在这里添加自定义响应头,比如Allow等
        return ResponseEntity.ok()
                .header("Allow", "OPTIONS, GET")
                .build();
    }

    // 其他需要认证的接口
    @GetMapping
    public ResponseEntity<String> getHealthStatus() {
        return ResponseEntity.ok("UP");
    }
}

这种方式适合需要对特定OPTIONS请求做自定义响应的场景,同时也能绕过认证。


为什么这些方案比自定义过滤器好?

这些都是Spring Security原生支持的配置方式,完全融入了Spring的安全过滤器链,不需要你自己去处理过滤器的顺序、认证上下文这些容易踩坑的细节,而且和你已经在用的CorsFilter完全兼容:CorsFilter会处理带Origin头的跨域预检请求,而这些配置会处理所有其他OPTIONS请求,两者各司其职,不会冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:13:59