[英]Global CORS configuration using Java Config is not working in Spring MVC
[英]Spring Global CORS configuration not working but Controller level config does
我正在尝试通过WebMvcConfigurerAdapter
全局配置 CORS,如下所示。 为了测试,我通过我创建的一个模拟外部服务的小节点应用程序访问我的 API 端点。 当我尝试这种方法时,响应不包含正确的标头并且失败
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 )。 我觉得我错过了一些简单的东西,因为注释控制器工作得很好。
为了使全局 CORS 配置工作,客户端必须在 OPTIONS 请求中添加这两个标头。
Origin: http://host.com
Access-Control-Request-Method: POST
但是,@CrossOrigin 注释只需要“Origin”标头。
您的客户端可能添加了“Origin”标头,但缺少“Access-Control-Request-Method”.....这就是为什么它适用于@CrossOrigin,但不适用于全局配置。
您没有在其中声明方法,默认情况下仅接受 get 方法。 尝试registry.allowedMethods("*");
我遇到了同样的问题,在设置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;
在遇到此问题中记录的确切问题后,我能够使 Spring Global CORS 配置工作。 我必须做两件事:
如果 allowCredentials 为真,则 allowedOrigins 不能为 *。 这记录在 Mozilla.org
从 spring XML 中删除 mvc:annotation-driven。 不能同时拥有 XML 配置和 @EnableWebMvc。 如果没有@EnableWebMvc,全局类将无法工作,因此必须删除 mvc:annotation-driven。
我刚刚遇到了完全相同的问题,该线程中的任何解决方案都不起作用。 我设法通过以下方法解决了它:
一个新的配置 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 配置。
我遇到了类似的问题。 我将 WebMvcConfigurerAdapter 更改为 WebMvcConfigurationSupport 并开始工作。
除此之外我还将xml配置文件中定义的RequestMappingHandlerMapping移到java配置中。
我在处理 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);
}
}
好运!
我认为您的映射定义缺少*
:
registry.addMapping("/api/query/**")
没有那个额外的*
,这个配置不会映射到/api/query/1121
请求路径(但它可以在/api/query/5
)。
我有一个类似的问题,似乎没有任何方法有效(除了为每个控制器使用@CrossOrigin
注释)。 我遵循了上面Bharat Singh 的解决方案,并在对 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 配置中没有找到此类映射 - 请注意!
我试图通过 WebMvcConfigurerAdapter 全局配置 CORS 显示你的日志。 我发现了日志消息,但出现了类似的错误
CORS 策略已阻止从源“某个源”访问“myurl”处的 XMLHttpRequest:对预检请求的响应未通过访问控制检查:请求的资源上没有“Access-Controll-Allow-Origin”标头。
我的案例也擅长@CrossOrigin,但不擅长全局配置。 我希望这会有所帮助。
原因是 web.xml。
1. 我有 <context:component-scan base-package="some base-package"> 但是类 WebConfig 不在 'some base-package' 包中,它在上层包中。 我将 WebConfig 移到了“一些基础包”包中,并且
2. 我删除了 <mvc:annotation-driven /> 因为我已经在 WebConfig 类中有 @EnableWebMvc 。
它有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.