Spring CORS没有'Access-Control-Allow-Origin'标题

时间:2016-01-29 18:28:49

标签: spring spring-mvc cors

将web.xml移植到java config后,我遇到了以下问题

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

基于一些Spring引用,尝试了以下尝试:

@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
        @Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }

}

所选值取自工作的web.xml过滤器:

<filter>    
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
</init-param> </filter> <filter-mapping>

<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

为什么Spring java配置方法不像web.xml文件那样有效?

13 个答案:

答案 0 :(得分:81)

registry.addMapping("/*")方法中将CorsMapping从registry.addMapping("/**")更改为addCorsMappings

查看此Spring CORS Documentation

来自documentation -

为整个应用程序启用CORS非常简单:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

您可以轻松更改任何属性,并仅将此CORS配置应用于特定路径模式:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("http://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(false).maxAge(3600);
    }
}

Controller method CORS configuration

@RestController
@RequestMapping("/account")
public class AccountController {
  @CrossOrigin
  @RequestMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

为整个控制器启用CORS -

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

您甚至可以使用控制器级和方法级CORS配置;然后,Spring将组合来自两个注释的属性以创建合并的CORS配置。

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://domain2.com")
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

答案 1 :(得分:7)

我们遇到了同样的问题,我们使用Spring的XML配置解决了它,如下所示:

在您的上下文xml文件中添加它

<mvc:cors>
    <mvc:mapping path="/**"
        allowed-origins="*"
        allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
        allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>

答案 2 :(得分:7)

有用的提示 - 如果您正在使用Spring数据,则需要采用不同的方法。

<script src="js/vendor.js"></script>
<script src="js/options.js"></script>

答案 3 :(得分:4)

如果您使用的是Spring Security ver&gt; = 4.2,则可以使用Spring Security的本机支持,而不是包含Apache:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

上面的示例是从Spring blog post复制的,您可以在其中找到有关如何在控制器上配置CORS,特定控制器方法等的信息。此外,还有XML配置示例以及Spring启动集成。

答案 4 :(得分:3)

根据Omar的回答,我在我的REST API项目中使用以下配置创建了一个名为WebConfig.java的新类文件:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("*");
  }
} 

这允许任何源访问API并将其应用于Spring项目中的所有控制器。

答案 5 :(得分:3)

Omkar的答案很全面。

但是全局配置部分的某些部分已更改。

根据spring boot 2.0.2.RELEASE reference

  

从4.2版开始,Spring MVC支持CORS。使用控制器方法   在Spring Boot中使用@CrossOrigin批注进行CORS配置   应用程序不需要任何特定的配置。全球CORS   可以通过注册WebMvcConfigurer Bean来定义配置   使用自定义的addCorsMappings(CorsRegistry)方法,如   以下示例:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

这篇文章中大多数答案都使用WebMvcConfigurerAdapter

The type WebMvcConfigurerAdapter is deprecated

  

从Spring 5开始,您只需要实现接口   WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {
     

这是因为Java 8在接口上引入了默认方法,   涵盖了WebMvcConfigurerAdapter类的功能

答案 6 :(得分:1)

公共类TrackingSystemApplication {

    public static void main(String[] args) {
        SpringApplication.run(TrackingSystemApplication.class, args);
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:4200").allowedMethods("PUT", "DELETE",
                        "GET", "POST");
            }
        };
    }

}

答案 7 :(得分:0)

我也有类似No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

的消息

我已经正确配置了cors,但RouterFuncion的webflux中缺少的是接受和内容类型标头 APPLICATION_JSON ,如这段代码:

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                              .and(accept(APPLICATION_JSON))
                              .and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}

答案 8 :(得分:0)

正如@Geoffrey指出的那样,对于Spring Security,您需要一种与此处所述不同的方法: Spring Boot Security CORS

答案 9 :(得分:0)

由于某种原因,如果仍然有人无法绕过CORS,请写出浏览器要访问您的请求的标头。

将此bean添加到您的配置文件中。

@Bean
public WebSecurityConfigurerAdapter webSecurity() {
    return new WebSecurityConfigurerAdapter() {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.headers().addHeaderWriter(
                    new StaticHeadersWriter("Access-Control-Allow-Origin", "*"));


        }
    };
}

通过这种方式,我们可以告诉浏览器,我们允许从所有来源进行交叉来源。如果要限制特定路径,则将“ *”更改为{'http://localhost:3000',“”}。

帮助性参考,以了解这种行为https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example

答案 10 :(得分:0)

我已经通过使用 @CrossOrigin 注释在Spring Boot中找到了解决方案。

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

答案 11 :(得分:0)

这是我解决Access-Control-Allow-Origin存在”问题的方法,经过多次尝试和研究。

添加Spring security后,很多开发者面临跨域问题,这就是解决该问题的方法。

  1. 添加自定义过滤器类的定义

    public class CsrfTokenLogger implements Filter {
    
     private Logger logger =
          Logger.getLogger(CsrfTokenLogger.class.getName());
    
    @Override
    public void doFilter(
    ServletRequest request, 
    ServletResponse response, 
    FilterChain filterChain) 
      throws IOException, ServletException {
    
      Object o = request.getAttribute("_csrf");
      CsrfToken token = (CsrfToken) o;
    
     filterChain.doFilter(request, response);
      }
     }
    
  2. 在配置类中添加自定义过滤器

    @Configuration
    public class ProjectConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) 
    throws Exception {
    
    http.addFilterAfter(
            new CsrfTokenLogger(), CsrfFilter.class)
        .authorizeRequests()
            .antMatchers("/login*").permitAll()
            .anyRequest().authenticated();
     }
    }
    

答案 12 :(得分:0)

我以这种方式解决了同样的问题。基本上添加此 @EnableWebSecurity 注释并添加 protected void configure(HttpSecurity http) throws Exception {}

从此改变:

@Configuration
public class WebConfig {

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("*");
        }
    };
}

}

到这里

@Configuration
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/**").authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
    http.cors().and().csrf().disable();
}

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("*");
        }
    }; 
  }
}