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

Spring Boot Security跨域API问题:安全接口跨域调用报错

解决Spring Security+JWT下受保护接口跨域问题

问题核心

浏览器发起跨域请求时会先发送OPTIONS预检请求,该请求不带Authorization头,会被Spring Security拦截判定为未授权;同时现有CORS配置缺少必要的头信息,导致跨域验证失败。


具体修复步骤

1. 放行OPTIONS预检请求

在SecurityConfig的configure方法中,添加对所有OPTIONS请求的全局放行,确保预检请求能正常通过:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .cors().and()
        .csrf().disable()
        .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 新增:放行所有OPTIONS请求
        .antMatchers("/ifrs/api/v1/user/token").permitAll()
        .anyRequest().authenticated()
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
        .exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
}

2. 完善CORS配置

补充允许的请求头、暴露的响应头,确保跨域请求能正常携带和读取必要信息:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("*")); // 允许所有请求头(包括Authorization)
    configuration.setExposedHeaders(Arrays.asList("Authorization")); // 暴露响应头给前端
    configuration.setAllowCredentials(true); // 允许携带凭证(如Cookie,按需开启)
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

3. 优化JWT过滤器(可选,增强鲁棒性)

显式判断OPTIONS请求并直接放行,避免过滤器逻辑意外拦截预检请求:

@Override
protected void doFilterInternal(
        HttpServletRequest request, 
        HttpServletResponse response, 
        FilterChain filterChain) throws ServletException, IOException {
    
    // OPTIONS请求直接放行
    if (HttpMethod.OPTIONS.name().equals(request.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
        filterChain.doFilter(request, response);
        return;
    }
    
    try {
        // 原有过滤器逻辑...
        String token = request.getHeader("Authorization");
        // ...其余代码保持不变
    } catch (ExpiredJwtException e) {
        throw e;
    } catch (Exception e) {
        throw e;
    }
}

4. 移除Controller上的@CrossOrigin注解(可选)

由于已通过Spring Security全局配置CORS,Controller层面的@CrossOrigin会与全局配置冲突,建议移除。


为什么原有@CrossOrigin无效?

Spring Security的过滤器链执行优先级高于Controller的拦截器,当预检请求被Security拦截时,还未到@CrossOrigin生效的阶段,因此必须在Security层面完成CORS配置并放行OPTIONS请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:06:48