由于项目是采用前后端分离开发的,所以前端项目访问服务器时需要跨域,所以就在服务器配置了
Access-Control-Allow-Origin 等于 * ,代码如下
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
private static final Logger logger = LoggerFactory.getLogger(WebMvcConfiguration.class);
@Bean
public CorsFilter corsFilter() {
logger.info("自定义过滤器->WebMvcConfiguration 执行");
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
/* 是否允许请求带有验证信息 */
corsConfiguration.setAllowCredentials(true);
/* 允许访问的客户端域名 */
corsConfiguration.addAllowedOrigin("*");
/* 允许服务端访问的客户端请求头 */
corsConfiguration.addAllowedHeader("*");
/* 允许访问的方法名,GET POST等 */
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
等进行漏扫的时候发现了Cors跨域漏洞,也就是任何域名都可以进行跨域访问,这样是不安全的,当发现这个漏洞的时候,第一反应是应该弄一个域名白名单,在服务器判断一下header 里面的 Origin的值是否在白名单里面,如果在则放行,如果不在则返回错误状态,于是就写了一个过滤器,进行判断,返回错误状态,但是后来发现,并没有解决问题,因为返回请求Access-Control-Allow-Origin 参数 还是带有修改后的域名
后来查了一下Access-Control-Allow-Origin 这个参数的作用,原来这个参数是告诉浏览器 这个配置下的域名可以跨域访问。
看到这里我又想到了可以在 HttpServletResponse 里面设置Access-Control-Allow-Origin 的值,然后就在相应里面设置为白名单的值,多个值用,号隔开。
设置完成之后,重新启动测试,发现还是不行,而且出现新的问题了,响应的Access-Control-Allow-Origin 值竟然有两条。
这让我很是费解,为什么会有两条,其中有一条是我在程序添加的,那么剩下的一条是怎么添加的,header 存储不是map结构吗,怎么会有重复的key,带着这些疑问我去看了看源码。发现不是我想的那么回事,HttpServletResponse 的实现类是ResponseFacade
找到实现类的 addHeader 方法
最后一步步发现存储的对象是 MimeHeaderField
心中的疑问是解除了,但是问题还是没有解决,既然有两条记录那肯定其他地方也有添加参数的地方,然后在本地测试了,并没有出现这种问题,线上出现这种问题,然后思路来了,因为是springboot项目,线上是tomcat容器下启动的,本地是main方法启动的,应该是tomcat容器配置文件的问题,这时候想起,设置跨域访问的配置文件,应该是在那时候添加的,jar 和war 启动方式有所差异,最后将两处保留了一处,问题解决。我这边是保留的自己写的filter