Spring Data REST出现Access-Control-Allow-Origin缺失CORS错误如何解决
问题解决方案
问题根因
- Spring Data REST配置的CORS映射路径
/*仅能匹配一级路径,无法覆盖多级接口路径,导致适配范围不全 - Spring Security启用
.cors()后未显式配置全局Cors规则,默认规则和Spring Data REST的配置不互通,普通接口无法复用CORS配置 - 自定义JWT授权过滤器未放行OPTIONS预检请求,预检请求不会携带认证头,会触发校验失败返回403,也不会返回CORS响应头
修复步骤
1. 修正Spring Data REST CORS映射路径
将映射路径修改为匹配所有层级的/**,如果前端需要跨域携带Cookie、认证头等凭证,将allowedOrigins("*")替换为allowedOriginPatterns("*")避免规则冲突:
@Component class DataRestConfig: RepositoryRestConfigurer { override fun configureRepositoryRestConfiguration(config: RepositoryRestConfiguration?, cors: CorsRegistry?) { cors?.addMapping("/**") ?.allowedOriginPatterns("*") ?.allowedMethods("GET", "PUT", "DELETE","PATCH","POST","OPTIONS") ?.allowCredentials(true) // 按需开启,前端无跨域传凭证需求可删除 } }
2. 配置Spring Security全局CORS规则
在WebSecurityConfig中显式注册CorsConfigurationSource Bean,统一所有接口(含非Spring Data REST接口)的CORS规则,确保CORS处理优先级高于权限校验:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) open class WebSecurityConfig(private val userDetailsServices: DatabaseUserDetailsServices, private val jwtService: JWTService): WebSecurityConfigurerAdapter() { @Value("\${auth.jwt.secret}") private var secret: String = "" override fun configure(http: HttpSecurity) { http .cors().configurationSource(corsConfigurationSource()).and() // 绑定自定义CORS配置 .csrf().disable() .addFilterAfter(JWTAuthorizationFilter(userDetailsServices, secret, jwtService),UsernamePasswordAuthenticationFilter::class.java) .authorizeRequests() .antMatchers(HttpMethod.POST,UserController.LOGIN_URL).permitAll() .antMatchers(HttpMethod.OPTIONS,"/**").permitAll() .anyRequest().authenticated() } // 注册全局CORS配置Bean @Bean open fun corsConfigurationSource(): CorsConfigurationSource { val configuration = CorsConfiguration() configuration.allowedOriginPatterns = listOf("*") configuration.allowedMethods = listOf("GET", "PUT", "DELETE","PATCH","POST","OPTIONS") configuration.allowedHeaders = listOf("*") configuration.allowCredentials = true // 按需开启,前端无跨域传凭证需求可删除 val source = UrlBasedCorsConfigurationSource() source.registerCorsConfiguration("/**", configuration) return source } }
3. 调整JWT过滤器放行OPTIONS请求
在JWTAuthorizationFilter的doFilterInternal方法最开头添加判断,OPTIONS请求直接放行不做token校验:
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) { // 放行OPTIONS预检请求 if (request.method == HttpMethod.OPTIONS.name()) { filterChain.doFilter(request, response) return } // 原有JWT校验逻辑保留 // ... }
验证效果
修复后预检OPTIONS请求会正常返回200状态码,响应头会自动携带Access-Control-Allow-Origin等CORS相关头部,Spring Data REST接口和普通业务接口都不会触发跨域错误。
内容的提问来源于stack exchange,提问作者Krisztian
相关产品推荐
相关产品推荐

