在我使用Spring 4.1之前。我有自己的Cors过滤器和拦截器。我也使用Tomcat 8.0.8,一切都很好。
当我将相同的应用程序移动到Tomcat 8.0.23时,CORS停止工作。
因此,我将应用程序更新为以下版本的Spring依赖:
org.springframework: 4.2.0.RC2
org.springframework.security: 4.0.1.RELEASE
org.springframework.security.oauth2: 2.0.7.RELEASE
org.springframework.ws.version: 2.2.0.RELEASE
spring.data.commons.core.version: 1.4.1.RELEASE
现在,我还更新了我的securityConfiguration.xml,使其具有适合安全性4.0.1.RELEASE的模式。
应用程序运行良好,除了CORS之外,所有更改都很完美。
所以我已经按照说明,并添加到我的WebMvcConfigurerAdapter实现类如下:
@Override
public void addCorsMappings(CorsRegistry registry) {
Properties prop = null;
try {
InputStream in = getClass().getResourceAsStream(
"/com/nando/config/cors.properties");
prop = new Properties();
prop.load(in);
in.close();
} catch (IOException e) {
prop = null;
}
if (prop != null) {
String domains = prop.getProperty("allowed.origins");
List<String> allowedOrigins = new ArrayList<String>(
Arrays.asList(domains.split(",")));
if (allowedOrigins.size() > 0) {
String[] arrayOrigins = null;
arrayOrigins = new String[allowedOrigins.size()];
arrayOrigins = allowedOrigins.toArray(arrayOrigins);
registry.addMapping("/**")
.allowedOrigins(arrayOrigins)
.allowedMethods("PUT, POST, GET, OPTIONS, DELETE")
.allowedHeaders("*")
.exposedHeaders("Authorization", "Content-Type")
.allowCredentials(false).maxAge(3600);
}
} else {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("PUT, POST, GET, OPTIONS, DELETE")
.allowedHeaders("*")
.exposedHeaders("Authorization", "Content-Type")
.allowCredentials(false).maxAge(3600);
}
}
仅仅这样做并不能解决问题,尽管使用Tomcat的调试器,我可以看到它被正确地执行和添加。我有一个属性文件,这样我就可以在不重新编译应用程序的情况下更改允许的域,就像我之前在4.1上使用自己的实现所做的那样。x春天。
因为我把这个应用程序作为OAuth2应用程序,所以我也实现了一个拦截器
在我的WebMvcConfigurerAdapter实现之前,我有一个拦截器,所以我曾试图将其添加到它:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CORSInterceptor());
super.addInterceptors(registry);
}
加载我的CORSInterceptor实现如下:
package com.nando.api.filters;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
*
* @author Nando
*
*/
@Component
public class CORSInterceptor extends HandlerInterceptorAdapter {
private Properties prop = new Properties();
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
InputStream in = getClass().getResourceAsStream("/com/nando/config/cors.properties");
prop.load(in);
in.close();
String domains = prop.getProperty("allowed.origins");
Set<String> allowedOrigins = new HashSet<String>(Arrays.asList(domains
.split(",")));
String originHeader = "";
originHeader = request.getHeader("Origin");
if (null != originHeader) {
for (String s : allowedOrigins) {
if (originHeader.contains(s)) {
if (!response.getHeaderNames().contains("Access-Control-Allow-Origin")) {
response.addHeader("Access-Control-Allow-Origin",
originHeader);
}
if (!response.getHeaderNames().contains("Access-Control-Allow-Methods")) {
response.addHeader("Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, DELETE, HEAD");
}
if (!response.getHeaderNames().contains("Access-Control-Allow-Credentials")) {
response.addHeader("Access-Control-Allow-Credentials", "true");
}
if (!response.getHeaderNames().contains("Access-Control-Allow-Headers")) {
response.addHeader("Access-Control-Allow-Headers",
"Authorization, Origin, Content-Type, x-Requested-with, Accept, Accept-Enconding, X-CSRF-Token");
}
if (!response.getHeaderNames().contains("Access-Control-Max-Age")) {
response.addHeader("Access-Control-Max-Age", "1800");
}
return true;
}
}
}
return true;
}
}
仍然不会有什么不同。
我不想将CORS过滤器添加到Tomcat,因为它不允许我在属性文件上设置域,迫使我在每次添加或删除域时编辑Tomcat实例配置。
看来我遇到难题了。
我还认为通过遵循Spring 4.2关于设置CORS的方向将使它更容易,但事实并非如此。
有人能帮忙吗?
谢谢,Carlos。
如果您想使用Spring CORS支持,我认为您应该:
- 将
allowedMethods("PUT, POST, GET, OPTIONS, DELETE")
更改为allowedMethods("PUT", "POST", "GET", "OPTIONS", "DELETE")
(这是一个变量参数) - 删除
allowedHeaders("*")
,它已经是默认值 - 删除
CORSInterceptor
- 删除Tomcat CORS过滤器
- 检查它是否可以在没有Spring安全的情况下工作
- 根据Brian的建议,给我们更多的HTTP请求/响应的细节
作为替代方案,请注意Spring Framework 4.2 GA还提供了一个CorsFilter
实现,可以与UrlBasedCorsConfigurationSource
结合使用,以提供全局CORS支持。
如果您正在使用Spring Boot(它支持Filter
bean),那么在您的@Configuration
注释类之一中可能是这样的:
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.addExposedHeader("Authorization");
config.addExposedHeader("Content-Type");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}