全局CORS配置失效:返回Invalid CORS Request错误
Spring Security CORS配置问题:返回「Invalid CORS Request」错误
在项目中基于Spring Security实现CORS时,OPTIONS预检请求返回「Invalid CORS Request」错误,调试发现自定义的CORS配置未被正确加载,AbstractHandlerMapping的corsInterceptor方法中config为null,自定义配置似乎被覆盖。
实现代码
SecurityFilterChain 配置
@Bean public SecurityFilterChain oidcFilterChain(final HttpSecurity http) throws Exception { return http .cors(withDefaults()) .securityMatcher(new OrRequestMatcher( new AntPathRequestMatcher(ApplicationConfig.BASE_PATH + "/**"))) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())) .build(); }
CorsConfigurationSource 配置
@Bean public UrlBasedCorsConfigurationSource corsConfigurationSource() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 创建CORS配置 CorsConfiguration config = new CorsConfiguration() { { setAllowedMethods(List.of( HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.OPTIONS.name())); } // 校验请求Origin是否允许 @Override public String checkOrigin(String requestOrigin) { if (requestOrigin == null || requestOrigin.isEmpty()) { return null; } String originToCheck = trimTrailingSlash(requestOrigin); try { // 获取当前JWT用户 Jwt jwtUser = SecurityContextUtil.getCurrentUser(); // 从JWT中获取允许的Origin列表 List<String> allowedOrigins = jwtUser.getClaimAsStringList(ALLOWED_ORIGINS); if (allowedOrigins != null) { for (String allowedOrigin : allowedOrigins) { if (originToCheck.equalsIgnoreCase(trimTrailingSlash(allowedOrigin))) { return requestOrigin; } } } } catch (SecurityException e) { log.error("SecurityException in CORS Configuration: {}", e.getMessage()); } // 不允许则返回null return null; } }; // 注册CORS配置到指定路径 source.registerCorsConfiguration(ApplicationConfig.BASE_PATH + "/**", config); return source; }
SecurityConfig类已添加@EnableWebSecurity和@Configuration注解
测试用例
@Test @WithJwtTestUser(user = JwtTestUser.PUK_11) void testPreflightRequest() throws Exception { mockMvc.perform(options("/cadastertask/cadasters/" + CADASTER_ID_101_PREMIUM1 + "/regulations/10/tasks") .header("Origin", "http://localhost:8081") .header("Access-Control-Request-Method", "GET")) .andDo(print()) .andExpect(status().isOk()) .andExpect(header().string("Access-Control-Allow-Origin", "http://localhost:8081")) .andExpect(header().string("Access-Control-Allow-Methods", "GET")) .andExpect(header().string("Access-Control-Max-Age", "3600")); }
响应详情
MockHttpServletRequest: HTTP Method = OPTIONS Request URI = /cadastertask/cadasters/97190101/regulations/10/tasks Parameters = {} Headers = [Origin:"http://localhost:8081", Access-Control-Request-Method:"GET"] Body = <no character encoding set> Session Attrs = {} Handler: Type = org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 403 Error message = null Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Allow:"GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH"] Content type = null Body = Invalid CORS request Forwarded URL = null Redirected URL = null Cookies = [] java.lang.AssertionError: Status expected:<200> but was:<403> Expected :200 Actual :403
已尝试的解决方案(均无效)
- 将
corsConfigurationSource()的返回类型改为CorsConfigurationSource接口 - 通过
CorsFilter返回自定义corsConfigurationSource()(此方法可行,但要求必须使用corsConfigurationSource而非过滤器)
求助
请问如何让Spring Security正确加载自定义的CORS配置,解决「Invalid CORS Request」错误?
内容的提问来源于stack exchange,提问作者gorecode
相关产品推荐
相关产品推荐

