Problems and Solutions of Cross domain Failure of Java CORS Caused by Spring Security Interceptor

  • 2021-11-01 03:18:28
  • OfStack

Adding Spring Security to the project where CORS has been set leads to the failure of cross-domain access. At first, 1 thought it was the problem of setting CORS incorrectly, but later found that it was caused by the interception conflict of Spring Security.

(1) Introduction to CORS

CORS is an W3C standard, and its full name is "Cross-domain Resource Sharing" (Cross-origin resource sharing).

It allows browsers to send XMLHttpRequest requests to cross-source servers, thus overcoming the limitation that AJAX can only be used from the same source.

response response header

响应头字段名称 作用
Access-Control-Allow-Origin 允许访问的客户端的域名
Access-Control-Allow-Credentials 是否允许请求带有验证信息,若要获取客户端域下的cookie时,需要将其设置为true。
Access-Control-Allow-Headers 允许服务端访问的客户端请求头
Access-Control-Allow-Methods 允许访问的HTTP请求方法
Access-Control-Max-Age 用来指定预检请求的有效期(秒),在有效期内不在发送预检请求直接请求。

For detailed introduction of Cors, please see Ruan 1feng's cross-domain resource sharing CORS for detailed explanation

(2) Configuration of CORS on the server side (Spring boot)

1. Write an filter directly to intercept all requests and add the above fields to the response header.

2. Inherit WebMvcConfigurerAdapter and rewrite addCorsMappings


public class CorsConfig extends WebMvcConfigurerAdapter {
     @Override
     public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/**")
                 .allowedHeaders("*")
                 .allowedMethods("*")
                 .allowedOrigins("*");
     }
}

Customize Filter, register


@Bean
 public FilterRegistrationBean corsFilter() {
     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
     CorsConfiguration config = new CorsConfiguration();
     config.addAllowedOrigin("*");
     config.setAllowCredentials(true);
     config.addAllowedHeader("*");
     config.addAllowedMethod("*");
     source.registerCorsConfiguration("/**", config);

     FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
     bean.setOrder(0);// Configure CorsFilter Priority 
     return bean;
 }

@ CrossOrigin notes


@CrossOrigin(
        origins = "*",
        allowCredentials = "true",
        allowedHeaders = "*",
        methods = RequestMethod.GET,
        maxAge = 3600
)

(3) Problems that arise

Even if the response header field is configured, it can't be accessed across domains. After repeated tests, it is found that GET request can be accessed, but PUT request can't be accessed. It suddenly occurred to me that a non-simple request will initiate a pre-check request of OPTIONS method, while I used Spring Security to intercept all requests and only open some requests, so it is necessary to set the request that does not intercept OPTIONS method in Spring Security.

Solution

Configure Spring Security and set not to intercept OPTIONS requests


HttpSecurity#authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS)
            .permitAll()

Configure CorsFilter priority, which is better than Spring Security configuration!


Related articles: