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

时间:2016-06-23 01:38:03

标签: java spring-mvc http-headers cors cross-domain

我正在尝试通过下面显示的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.

Global Config

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)。我觉得我错过了一些简单的东西,因为注释控制器工作得很好。

10 个答案:

答案 0 :(得分:14)

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

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

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

    如果allowCredentials为true,则
  1. allowedOrigins不能为*。这在Mozilla.org

  2. 中有记录
  3. 从spring XML中删除mvc:annotation-driven。不能同时拥有XML配置和@EnableWebMvc。如果没有@EnableWebMvc,全局类将无法工作,因此必须删除mvc:annotation-driven。

答案 3 :(得分:1)

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

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

答案 4 :(得分: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配置。

答案 5 :(得分:1)

在Spring MVC应用程序(不是Spring Boot)上工作时,我遇到了同样的问题。 解决问题的唯一方法是在spring安全过滤器链中显式添加一个cors过滤器:

public class MySecurityInitializer extends AbstractSecurityWebApplicationInitializer {

  protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
    final FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", corsFilter());
    corsFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
  }

  protected CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(Arrays.asList(CrossOrigin.DEFAULT_ORIGINS));
    config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
    config.setAllowedHeaders(Arrays.asList(CrossOrigin.DEFAULT_ALLOWED_HEADERS));
    config.setAllowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS);
    config.setMaxAge(CrossOrigin.DEFAULT_MAX_AGE);
    source.registerCorsConfiguration("/**", config);

    return new CorsFilter(source);
  }

}

好运!

答案 6 :(得分:0)

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

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

如果没有额外的*,此配置不会映射到/api/query/1121请求路径(但它可以在/api/query/5上运行。)

答案 7 :(得分: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配置中找到此类映射-请注意这一点!

答案 8 :(得分: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;

答案 9 :(得分:0)

我正尝试通过WebMvcConfigurerAdapter全局配置CORS,并与日志一起显示。 而且我发现了日志消息,但出现了类似的错误

从源“某个源”对“ myurl”处的XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:没有“ Access-Controll-Allow-Origin”标头在请求的资源。

我的案例也擅长@CrossOrigin,但在全局配置中却不行。 希望对您有所帮助。

原因是web.xml。

1。 我有 但是类WebConfig不在“某些基础包”包中,而是在上层包中。 我将WebConfig移至“一些基本软件包”软件包中,并且

2。 我删除了,因为我在WebConfig类中已经有@EnableWebMvc。

有效。