Spring Global CORS配置无效,但控制器级配置有效

问题描述 投票:26回答:7

我试图通过下面显示的WebMvcConfigurerAdapter全局配置CORS。测试我通过我创建的小节点应用程序来模拟外部服务。当我尝试这种方法时,响应不包含正确的标题,并失败

XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:333' is therefore not allowed access.

全球配置

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/query/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
}

但是,当我使用@CrossOrigin注释时,它可以很好地响应正确的标题。

@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/query", produces = MediaType.APPLICATION_JSON_VALUE)
public class QueryController {
   ......
}

产生

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:333

我缺少什么使全局配置工作(按照这里的说明https://spring.io/blog/2015/06/08/cors-support-in-spring-framework)。我觉得我错过了一些简单的东西,因为注释控制器工作得很好。

java spring-mvc http-headers cors cross-domain
7个回答
14
投票

为了使全局CORS配置起作用,客户端必须在OPTIONS请求中添加这两个头。

Origin: http://host.com
Access-Control-Request-Method: POST

但是@CrossOrigin注释只需要“Origin”标题。 您的客户端可能会添加“Origin”标头,但缺少“Access-Control-Request-Method”.....这就是为什么它适用于@CrossOrigin,但不适用于全局配置。


4
投票

你没有在它声明的方法,默认情况下只接受get方法。试试registry.allowedMethods("*");


2
投票

在遇到此问题中记录的确切问题后,我能够使Spring Global CORS配置正常工作。我不得不做两件事:

  1. 如果allowCredentials为true,则allowedOrigins不能为*。这在Mozilla.org上有记录
  2. 从spring XML中删除mvc:annotation-driven。不能同时拥有XML配置和@EnableWebMvc。没有@EnableWebMvc,全局类将无法工作,因此必须删除mvc:annotation-driven。

1
投票

我遇到了类似的问题。我将WebMvcConfigurerAdapter更改为WebMvcConfigurationSupport,它开始工作。

除此之外,我还将xml配置文件中定义的RequestMappingHandlerMapping移动到java配置。


1
投票

我刚刚遇到了完全相同的问题,这个线程中的解决方案都没有。我已成功解决了以下问题:

一个新的配置bean:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilterConfiguration {

  @Bean
  public CorsFilter corsFilter() {
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      CorsConfiguration config = new CorsConfiguration();
      config.setAllowCredentials(true);
      config.addAllowedOrigin("*");
      config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
      config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
      source.registerCorsConfiguration("/**", config);
      return new CorsFilter(source);
  }
}

修改我的web.xml以为所有URL添加新过滤器:

<filter>
  <filter-name>corsFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>corsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

显然你可以相应地修改cors配置。


0
投票

我认为您的映射定义缺少*

registry.addMapping("/api/query/**")

没有额外的*,这个配置没有映射到/api/query/1121请求路径(但它可以在/api/query/5上工作)。


0
投票

我有一个类似的问题,似乎没有任何方法可行(除了为每个控制器使用@CrossOrigin注释)。我按照上面的Bharat Singh's解决方案进行了一些Spring Framework内部调试 - 这对我有用(Spring Boot 2.0.6 + Spring Framework 5.0.10):

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

/* (non-Javadoc)
 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
 */
@Override
protected void addCorsMappings(CorsRegistry registry) {
    //NOTE: servlet context set in "application.properties" is "/api" and request like "/api/session/login" resolves here to "/session/login"!
    registry.addMapping("/**")
        .allowedMethods("GET", "POST", "PUT", "DELETE")
        .allowedOrigins("*")
        .allowedHeaders("*")
        .allowCredentials(false);
    }
}

最初当我使用"/api/**"映射时,它是在Spring中配置的,但是由于应用程序是使用"/api"上下文部署的 - 像"/api/session/login"这样的请求内部映射到"/session/login"并且没有找到CORS配置中的这种映射 - 请注意这一点!


0
投票

我遇到了同样的问题,在设置了maxAge属性之后,一切都开始正常了!

@Bean
public WebMvcConfigurer CORSConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                    .maxAge(-1)   // add maxAge
                    .allowCredentials(false);
        }
    };
}

如果检查CrossOrigin注释,则它具有分配给该属性的默认值

/**
 * <p>By default this is set to {@code 1800} seconds (30 minutes).
 */
long maxAge() default -1;
© www.soinside.com 2019 - 2024. All rights reserved.