Spring的CorsFilter会失效的原因及解决方法

 更新时间:2023年09月28日 11:11:04   作者:帆_布  
众所周知CorsFilter是Spring提供的跨域过滤器,我们可能会做以下的配置,基本上就是允许任何跨域请求,我利用Spring的CorsFilter做跨域操作但是出现报错,接下来小编就给大家介绍一Spring的CorsFilter会失效的原因及解决方法,需要的朋友可以参考下

1. 背景分析

众所周知CorsFilter是Spring提供的跨域过滤器,我们可能会做以下的配置,基本上就是允许任何跨域请求

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名进行跨域调用
        config.addAllowedOriginPattern("*");
        //允许跨越发送cookie
        config.setAllowCredentials(true);
        //放行全部原始头信息
        config.addAllowedHeader("*");
        //允许所有请求方法跨域调用
        config.addAllowedMethod("*");
        //跨域允许时间,单位:秒
        config.setMaxAge(60 * 60L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

我们的系统主要是SpringBoot+SpringSecurity构成的,我利用Spring的CorsFilter做跨域操作也没问题吧

但就是在这种简单的情况下前端还是爆出了跨域情况

这就头大了呀,毕竟网上的教程和我的经验分析都觉得是可以的

2. 问题分析

这个时候就没办法了,只能本地Debug + 分析源码,看看问题所在地

然后我是利用Apifox里面保存的请求实例,然后复制一份(这里面有系统的认证参数),请求方式改为了OPTIAN了,然后其他杂七杂八的请求头也从前端中复制到新的请求实例中了

然后启动项目,打好断点

最终发现进入了CorsFilter的doFilterInternal方法,并且判断成功,确实是一个OPTIAON, 响应头也已经填充了对应的响应头,ApiFox也提示请求正常

这就离谱了,dev环境不可以,local环境就可以了,这个时候我决定不偷懒了,新建一个请求实例,完全照搬前端发起的请求

这个时候问题就稍微浮出水面了,我发现CorsFilter都没进去,Apifox就已经提示了跨域了

于是我继续分析向上的流程,大家看下面的这个图,这是注册到Tomcat中的过滤器组成的过滤器链

先看前三个过滤器:

  • OrderedCharacterEncodingFilter:确认本次请求的编码格式
  • OrderedCharacterEncodingFilter:为PUT、PATCH、DELETE这样的请求方式,将请求体转为键值对形式,然后通过 getParameter 读取
  • OrderedRequestContextFilter:用于初始化 LocaleContextHolder 和 RequestContextHolder 的过滤器

然后我们再看后面的springSecurityFilterChaincorsFilter,注意这里是springSecurityFilterChain在前,也就是会先执行

我最新的这一次跨域请求是没有携带认证参数的,也就是说会被SpringSecurity的ExceptionTranslationFilter处理访问被拒绝异常,也就不会走后面的corsFilter,也就不会写入响应头的相关参数了

3. 解决办法

3.1 SpringSecurity的角度

问题分析到这其实解决思路就很简单了,要么我们改用SpringSecurity提供的跨域支持,就像下面这样

3.2 SpringBoot的角度

要么我们就改变注册到Tomcat的CorsFilter的执行顺序,我当时也是这样处理的,看下图我介绍的三个过滤器均在 springSecurityFilterChain之前执行,并且他们的顺序是保持一致的,也就是SpringBoot一定做了排序的

我们可以先看这三个过滤器的共同点:他们都同时实现了OrderedFilter接口,并且重写getOrder()方法

在这种情况下,我就自己写了一个CorsFilter, 并实现了OrderedFilter

然后我们就可以发现过滤器的顺序发生了变化

前端也正常的发起了跨域请求,业务流程也可以继续跑了

4. 总结

总结:

  • 其实跨域问题很好解决,本质上就是后端要设置对应的响应头
  • 我这里出现问题还是因为自己偷懒了,直接复制以前的请求实例发起OPTION请求
  • 还有就是没想起来SpringBoot和SpringSecurtiy中处理跨域会有一个先后顺序(冲突)的问题才导致的
  • 当然Spring中处理跨域其实不只CorsFilter这一种方式,还可以通过RequestMappingHandlerMapping完成,就在下面的地方,这个后续在介绍

以上就是Spring的CorsFilter会失效的原因及解决方法的详细内容,更多关于Spring CorsFilter失效的资料请关注脚本之家其它相关文章!

相关文章

  • Springboot在IDEA热部署的配置方法

    Springboot在IDEA热部署的配置方法

    这篇文章主要介绍了Springboot在IDEA热部署的配置方法,给大家补充介绍了Intellij IDEA 4种配置热部署的方法,需要的朋友可以参考下
    2018-04-04
  • Spring Boot中记录用户系统操作流程

    Spring Boot中记录用户系统操作流程

    这篇文章主要介绍了如何在Spring Boot中记录用户系统操作流程,将介绍如何在Spring Boot中使用AOP(面向切面编程)和日志框架来实现用户系统操作流程的记录,需要的朋友可以参考下
    2023-07-07
  • Servlet实现分页效果

    Servlet实现分页效果

    这篇文章主要为大家详细介绍了Servlet实现分页效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 详解JAVA 字节流和字符流

    详解JAVA 字节流和字符流

    这篇文章主要介绍了JAVA 字节流和字符流的的相关资料,文中讲解非常的细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • Java中的Runnable,Callable,Future,FutureTask的比较

    Java中的Runnable,Callable,Future,FutureTask的比较

    这篇文章主要介绍了Java中的Runnable,Callable,Future,FutureTask的比较的相关资料,需要的朋友可以参考下
    2017-02-02
  • SpringBoot3各种配置的优先级对比小结

    SpringBoot3各种配置的优先级对比小结

    SpringBoot3提供了多种配置来源以满足不同场景下的需求,本文详细介绍了SpringBoot3中的配置优先级对比小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-12-12
  • java 使用异常的好处总结

    java 使用异常的好处总结

    这篇文章主要介绍了java 使用异常的好处总结的相关资料,需要的朋友可以参考下
    2017-03-03
  • java实现pdf文件截图的方法【附PDFRenderer.jar下载】

    java实现pdf文件截图的方法【附PDFRenderer.jar下载】

    这篇文章主要介绍了java实现pdf文件截图的方法,结合实例形式分析了java基于PDFRenderer.jar进行pdf文件截图的相关操作技巧,并附带PDFRenderer.jar文件供读者下载使用,需要的朋友可以参考下
    2018-01-01
  • springboot时间格式化的五种方法总结(解决后端传给前端的时间显示不一致)

    springboot时间格式化的五种方法总结(解决后端传给前端的时间显示不一致)

    这篇文章主要给大家介绍了关于springboot时间格式化的五种方法,文中介绍的方法解决了后端传给前端的时间显示不一致,文中通过图文以及代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • SpringBoot注解@MapperScan的实现

    SpringBoot注解@MapperScan的实现

    @MapperScan是MyBatis和MyBatis-Plus提供的SpringBoot注解,用于自动扫描并注册 Mapper 接口,使其能够被 Spring 容器管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-05-05

最新评论