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

Spring Security CORS不生效,请求返回403/401问题求助

Spring Security跨域+认证问题:401/403排查与解决

问题核心原因

  • 未配置http.cors()时返回401:Spring Security的认证过滤器优先级高于默认CORS过滤器,Angular发起跨域请求时,浏览器会先发送OPTIONS预检请求,该请求不会携带任何认证令牌(比如JWT),直接被认证过滤器判定为未授权,返回401。
  • 禁用CORS或自定义Bean无效时返回403:配置cors(cors->cors.disable())会直接关闭Spring Security的CORS支持,浏览器触发同源策略拦截请求返回403;同时你定义的CorsConfigurationSourceBean会因CORS被禁用而完全不生效。

正确配置示例

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                // 启用CORS,并指定使用自定义配置源
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                .authorizeHttpRequests(r -> r
                        // 优先放行所有OPTIONS预检请求,避免认证拦截
                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        .anyRequest().authenticated());

        return http.build();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        // 允许Angular所在的源跨域
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        // 包含预检请求的OPTIONS方法
        configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS"));
        // 允许携带认证头、内容类型头等关键请求头
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
        // 允许浏览器暴露后端返回的自定义响应头(按需配置)
        configuration.setExposedHeaders(Arrays.asList("X-Custom-Header"));
        // 如果需要携带Cookie或凭证,必须开启此项(Angular端需同步设置withCredentials: true)
        configuration.setAllowCredentials(true);
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

请求头相关关键说明

  • OPTIONS预检请求:跨域场景下,浏览器会先发送OPTIONS请求确认后端是否允许跨域,该请求不携带任何用户凭证,必须在Security规则中优先放行,否则会被认证逻辑拦截。
  • AllowedHeaders配置:必须包含前端请求中实际携带的所有自定义头,比如Authorization(JWT认证时前端会把token放在这个头里)、Content-Type(发送JSON格式数据时必需),缺少的话浏览器会直接拒绝发送实际请求。
  • AllowCredentials:如果你的认证依赖Cookie,或者需要前端携带凭证请求,必须开启该选项,同时Angular的HTTP请求要设置withCredentials: true,否则浏览器不会保存或发送相关凭证。
  • CORS过滤器顺序:启用http.cors()后,Spring Security会自动将CORS过滤器置于认证过滤器之前,确保跨域规则先被校验,再执行认证逻辑,避免预检请求被误拦截。

额外注意事项

  • 如果Angular请求配置了withCredentials: true,setAllowedOrigins不能设置为*,必须指定具体的源(比如http://localhost:4200),否则浏览器会拒绝跨域请求。
  • 无需修改/**路径,该配置表示所有接口都应用跨域规则,符合你的场景需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:22:49