Spring Boot CORS:源被拒绝时修改ServletResponse的方法
解决Spring Security CORS拒绝请求时自定义响应头的问题
因为Spring Security的CORS过滤器是在Filter链的最前端执行的,被CORS规则拒绝的请求根本无法到达自定义Filter,所以需要通过重写Spring Security的CORS处理逻辑来实现需求。
步骤1:自定义CorsProcessor
Spring Security默认使用DefaultCorsProcessor处理CORS校验,我们可以重写它的processRequest方法,在校验失败时添加自定义响应头:
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsProcessor; import org.springframework.web.cors.DefaultCorsProcessor; import org.springframework.web.cors.CorsUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CustomCorsProcessor extends DefaultCorsProcessor { @Override public boolean processRequest(CorsConfiguration config, HttpServletRequest request, HttpServletResponse response) throws IOException { // 执行默认CORS校验逻辑 boolean corsValid = super.processRequest(config, request, response); // 校验失败时添加自定义响应头 if (!corsValid && CorsUtils.isPreFlightRequest(request)) { // 替换成你需要的唯一响应头 response.addHeader("X-CORS-DENY-ID", "your-unique-identifier"); } return corsValid; } }
步骤2:在SecurityFilterChain中配置自定义处理器
修改你的SecurityChain配置类,将自定义的CorsProcessor注入到CORS配置中:
@Configuration @EnableWebSecurity @EnableMethodSecurity public class SecurityChain { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorizeRequests -> authorizeRequests .requestMatchers(HttpMethod.GET, "/**").permitAll() .requestMatchers(HttpMethod.POST, "/**").permitAll() .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers(HttpMethod.HEAD, "/**").permitAll()) .cors(cors -> cors .configurationSource(configureCors()) .processor(new CustomCorsProcessor())); // 绑定自定义处理器 return http.build(); } CorsConfigurationSource configureCors() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOriginPatterns(Arrays.asList("origin1", "origin2")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS", "HEAD")); configuration.setAllowedHeaders(Arrays.asList("*")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
注意事项
- 移除控制器上的
@CrossOrigin注解,全局CORS配置和局部注解会导致冲突,以全局配置为准。 - 仅针对预检请求(OPTIONS方法)添加头即可,因为浏览器发起CORS请求时,会先发送预检请求确认权限,预检失败后不会发送实际请求。
内容的提问来源于stack exchange,提问作者Carter Smith
相关产品推荐
相关产品推荐

