SpringBoot跨域处理 
@CrossOrigin(局部跨域) 
作用在方法上 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @RestController public  class  IndexController  {    @CrossOrigin(value = "http://localhost:8082")      @GetMapping("/hello")      public  String hello ()  {         return  "get hello" ;     }     @CrossOrigin(value = "http://localhost:8082")      @PostMapping("/hello")      public  String hello2 ()  {         return  "post hello" ;     } } 
 
作用在类上 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @CrossOrigin(origins = "http://example.com", maxAge = 3600) @RestController @RequestMapping("/account") public  class  AccountController  {    @RequestMapping(method = RequestMethod.GET, path = "/{id}")      public  Account retrieve (@PathVariable  Long id)  {              }     @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")      public  void  remove (@PathVariable  Long id)  {              } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 @Configuration public  class  WebMvcConfig  implements  WebMvcConfigurer  {      @Override      public  void  addCorsMappings (CorsRegistry registry)  {         registry.addMapping("/**" )                 .allowedHeaders("Content-Type" ,"X-Requested-With" ,"accept,Origin" ,"Access-Control-Request-Method" ,"Access-Control-Request-Headers" ,"token" )                 .allowedMethods("*" )                 .allowedOrigins("*" )                 .allowCredentials(true );     } } 
 
SpringSecurity跨域处理 
跨域配置详解 
如果使用了 Spring Security,上面的跨域配置会失效,因为请求被 Spring Security 拦截了
在项目中使用 Spring Security,我们必须采取额外的步骤确保它与 CORS 协作良好。这是因为 CORS 需要首先处理,否则,Spring Security 会在请求到达 Spring MVC 之前将其拒绝
1 2 3 4 5 6 7 8 @Configuration public  class  SpringSecurityConfig  extends  WebSecurityConfigurerAdapter  {    @Override      protected  void  configure (HttpSecurity http)  throws  Exception {         http.cors().and()...     } } 
 
可以配置 CORS 以覆盖默认的 Spring Security CORS 处理器。为此,我们需要添加一个 CorsConfigurationSource Bean,使用 CorsConfiguration 实例来处理 CORS 配置。如果添加了 CorsFilter Bean,http.cors() 方法就会使用 CorsFilter,否则就会使用 CorsConfigurationSource。如果两者都未配置,则使用 Spring MVC pattern inspector handler。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 public  class  CorsConfigurer <H extends  HttpSecurityBuilder <H>>		extends  AbstractHttpConfigurer <CorsConfigurer<H>, H> {     private  static  final  String  HANDLER_MAPPING_INTROSPECTOR  =  "org.springframework.web.servlet.handler.HandlerMappingIntrospector" ;     private  static  final  String  CORS_CONFIGURATION_SOURCE_BEAN_NAME  =  "corsConfigurationSource" ;     private  static  final  String  CORS_FILTER_BEAN_NAME  =  "corsFilter" ;     private  CorsConfigurationSource configurationSource;     public  CorsConfigurer ()  {     }     public  CorsConfigurer<H> configurationSource (              CorsConfigurationSource configurationSource)  {        this .configurationSource = configurationSource;         return  this ;     }     @Override      public  void  configure (H http)  {         ApplicationContext  context  =  http.getSharedObject(ApplicationContext.class);         CorsFilter  corsFilter  =  getCorsFilter(context);         if  (corsFilter == null ) {             throw  new  IllegalStateException (                     "Please configure either a "  + CORS_FILTER_BEAN_NAME + " bean or a "                              + CORS_CONFIGURATION_SOURCE_BEAN_NAME + "bean." );         }         http.addFilter(corsFilter);     }     private  CorsFilter getCorsFilter (ApplicationContext context)  {         if  (this .configurationSource != null ) {             return  new  CorsFilter (this .configurationSource);         }                  boolean  containsCorsFilter  =  context                 .containsBeanDefinition(CORS_FILTER_BEAN_NAME);         if  (containsCorsFilter) {             return  context.getBean(CORS_FILTER_BEAN_NAME, CorsFilter.class);         }                  boolean  containsCorsSource  =  context                 .containsBean(CORS_CONFIGURATION_SOURCE_BEAN_NAME);         if  (containsCorsSource) {             CorsConfigurationSource  configurationSource  =  context.getBean(                     CORS_CONFIGURATION_SOURCE_BEAN_NAME, CorsConfigurationSource.class);             return  new  CorsFilter (configurationSource);         }                  boolean  mvcPresent  =  ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,                 context.getClassLoader());         if  (mvcPresent) {             return  MvcCorsFilter.getMvcCorsFilter(context);         }         return  null ;     }     static  class  MvcCorsFilter  {         private  static  final  String  HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME  =  "mvcHandlerMappingIntrospector" ;         private  static  CorsFilter getMvcCorsFilter (ApplicationContext context)  {             if  (!context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {                 throw  new  NoSuchBeanDefinitionException (HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, "A Bean named "  + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type "  + HandlerMappingIntrospector.class.getName()                         + " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext." );             }                          HandlerMappingIntrospector  mappingIntrospector  =  context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);             return  new  CorsFilter (mappingIntrospector);         }     } } 
 
CorsConfigurationSource(全局跨域) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Configuration public  class  SpringSecurityConfig  extends  WebSecurityConfigurerAdapter  {    @Override      protected  void  configure (HttpSecurity http)  throws  Exception {         http.authorizeRequests()             .anyRequest()             .permitAll()             .and()             .formLogin()             .permitAll()             .and()             .httpBasic()             .and()                          .cors()                                       .and()             .csrf()             .disable();     }          @Bean      public  CorsConfigurationSource corsConfigurationSource ()  {         CorsConfiguration  configuration  =  new  CorsConfiguration ();         configuration.setAllowedOrigins(Arrays.asList("*" ));         configuration.setAllowedMethods(Arrays.asList("*" ));         configuration.setAllowedHeaders(Arrays.asList("*" ));         UrlBasedCorsConfigurationSource  source  =  new  UrlBasedCorsConfigurationSource ();         source.registerCorsConfiguration("/**" , configuration);         return  source;     } } 
 
CosFilter(全局跨域) 
还有一种情况就是支持 OAuth2 相关接口的跨域,比如用户要访问 OAuth2 中的 /oauth/token 等接口,可以配置一个全局的 CorsFilter 跨域过滤器类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Configuration public  class  GlobalCorsConfig  {         @Bean      public  CorsFilter corsFilter ()  {                  CorsConfiguration  config  =  new  CorsConfiguration ();                  config.addAllowedOrigin("*" );                  config.setAllowCredentials(true );                  config.addAllowedMethod("*" );                  config.addAllowedHeader("*" );                  config.addExposedHeader("*" );                    UrlBasedCorsConfigurationSource  configSource  =  new  UrlBasedCorsConfigurationSource ();         configSource.registerCorsConfiguration("/**" , config);                    return  new  CorsFilter (configSource);     } } 
 
自定义Filter(全局跨域) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  class  CorsFilter  extends  OncePerRequestFilter  {         @Override      protected  void  doFilterInternal (HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  throws  ServletException, IOException {         String  orignalHeader  =  StringUtils.defaultIfBlank(request.getHeader("Origin" ), "*" );                  response.setHeader("Access-Control-Max-Age" , "3600" );                  response.setHeader("Access-Control-Allow-Headers" , request.getHeader("Access-Control-Request-Headers" ));         response.setHeader("Access-Control-Allow-Origin" , orignalHeader);         response.setHeader("Access-Control-Allow-Credentials" , "true" );         response.setHeader("Access-Control-Allow-Methods" , "POST, GET, OPTIONS, DELETE, PUT" );         filterChain.doFilter(request, response);     } } 
 
1 2 3 4 5 6 7 8 @Configuration public  class  WebMvcConfig  extends  WebSecurityConfigurerAdapter  {         @Override      public  void  configure (HttpSecurity http)  throws  Exception {         http.addFilterBefore(new  CorsFilter (), WebAsyncManagerIntegrationFilter.class);     } }