1. 为什么SpringSecurity需要单独处理跨域问题
跨域问题本质上是浏览器出于安全考虑实施的同源策略限制。当我们在前端项目中调用后端API时,如果协议、域名或端口任一不同,就会触发浏览器的跨域限制。有趣的是,即使SpringBoot已经通过@CrossOrigin注解或WebMvcConfigurer配置了全局跨域,当引入SpringSecurity后这些配置仍然可能失效。
这是因为SpringSecurity的过滤器链优先级非常高。请求会先经过Security的过滤器进行认证和授权检查,在这个过程中如果响应头中没有正确的CORS配置,浏览器就会直接拦截请求。我曾在项目中遇到过这样的场景:前端开发人员已经配置了axios的withCredentials,后端也加了@CrossOrigin(origins="*"),但请求依然失败。通过抓包发现,OPTIONS预检请求直接被SpringSecurity拦截返回了403。
重要提示:SpringSecurity默认会拦截OPTIONS请求,而CORS的预检请求正是使用OPTIONS方法。这就是为什么需要专门为SpringSecurity配置CORS处理。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. SpringSecurity中配置CORS的三种方式
2.1 基于HttpSecurity的配置方法
这是最推荐的生产环境配置方式,可以与SpringSecurity的其他配置保持风格一致。以下是一个完整的配置示例:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().configurationSource(corsConfigurationSource())
.and()
// 其他安全配置...
.csrf().disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE"));
configuration.setAllowCredentials(true);
configuration.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
