spring 跨域問題CORS

最近的開發過程中,使用spring集成了spring-cloud-zuul,但是由於服務部署在線上,本地調試存在跨域問題,導致報錯:403 forbidden Invalid CORS request 解決問題的過程中總結了spring的跨域處理策略(精讀spring和spring boot的文檔都能找到解決方案)

訪問我的個人網站獲取更多文章

項目情況:spring +spring boot+spring-cloud-zuul+spring security

問題

之前使用下方介紹的配置2進行了跨域配置,但是採用zuul的時候,報錯403,測試之後發現問題在於filter的執行順序,給出了3的解決方案;3正常之後,發現本地調試未登錄情況下,前端不能捕獲401錯誤

Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:8088' is therefore not allowed access. 
The response had HTTP status code 401.

猜測是spring security的filter在全局配置的跨域filter之前,所以有了4的配置。

方案

spring中可以採用的跨域配置方式如下:

RequestMapping

在一般性的配置中,在controller前添加@CrossOrigin即可使用spring的默認配置,允許跨域
該註解也可以配置一些設定,適合針對個別的controller

webconfig的方式配置全局跨域

@Configuration
public class JxWebMvcConfiguration extends WebMvcConfigurerAdapter {

  /**
  * Cross Origin Resource Support(CORS) for the Spring MVC.
  * automatically.
  * https://my.oschina.net/wangnian/blog/689020
  * http://spring.io/guides/gs/rest-service-cors/
  */
  /* @Override
  public void addCorsMappings(CorsRegistry registry) {
  registry.addMapping("*")
  .allowedOrigins("*").exposedHeaders("x-total-count","x-auth-token")
  .allowedMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE");
  }*/
}

這種方式的缺陷是,filter的順序是固定的,在引入第三方組件的時候可能會因爲filter滯後,導致出錯

定製Filter

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

參考Spring Document

方案3缺陷

在3中,我使用zuul的時候,的確解決了跨域問題,但是spring security的filter還是在其前邊,引起登錄的時候不能正常捕獲401錯誤

@Bean
    public Filter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.addExposedHeader("x-auth-token");
        config.addExposedHeader("x-total-count");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {       
        httpSecurity.addFilterBefore(corsFilter(), ChannelProcessingFilter.class);
      }

參考

Spring Boot Data Rest + CORS not being enabled properly for OPTIONS/DELETE

標準filter的順序

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章