Cors跨域白名单配置失效排查 过滤器Filter

1.指定能访问的客户端域名,后测试发现白名单未生效,非白名单的也能访问.

    @Bean
    @Conditional(CorsFilterCondition.class)
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        //是否允许请求带有验证信息
        corsConfiguration.setAllowCredentials(true);
        // 允许访问的客户端域名
        corsConfiguration.addAllowedOriginPattern("http://localhost:3000");
//        corsConfiguration.addAllowedOriginPattern("*");
        // 允许服务端访问的客户端请求头
        corsConfiguration.addAllowedHeader("*");
        // 允许访问的方法名,GET POST等
        corsConfiguration.addAllowedMethod("*");
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }

2.那么问题就是指向了 Filter, 为什么配置没有生效?

        在 DefaultCorsProcessor 的 processRequest 方法中发现 

        在判断 response(响应)  的 ACCESS_CONTROL_ALLOW_ORIGIN(访问-控制-允许-源)                是直接返回true,没有到匹配白名单的方法( handleInternal )中,

        如图

3.那么就能确定之前的Filter中有给 response  的 ACCESS_CONTROL_ALLOW_ORIGIN赋值操作

        那就断点查看Filter 中有哪些过滤器是在 CorsFilter 之前的,发现有个MagicCorsFilter

        进一步查看源码

        发现此处 Origin 为空则赋值 *  否则赋值 Origin   
       

刚好给response(响应)  的 ACCESS_CONTROL_ALLOW_ORIGIN 赋值使其跳过了后的校验

解决

找到了问题那就好解决了,

方案1.提升CorsFilter的优先级别在MagicCorsFilter之前,
方案2.降低MagicCorsFilter的优先级别在CorsFilter之后

我采用的是方案1 如下代码

        //优先级别提升带最高
        filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);

    @Value("${cors.origins:*}")
    private String origins;

    @Bean
    public FilterRegistrationBean<CorsFilter> newCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildCorsConfig());
        FilterRegistrationBean<CorsFilter> filterRegistrationBean = new FilterRegistrationBean<>(new CorsFilter(source));
        
        //优先级别提升带最高
        filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        
        return filterRegistrationBean;
    }
    private CorsConfiguration buildCorsConfig() {
        CorsConfiguration corsConfig = new CorsConfiguration();


        corsConfig.addAllowedOriginPattern("白名单");
        //其他配置自行添加

        corsConfig.setAllowCredentials(true);
        return corsConfig;
    }

提升后

再次测试问题解决

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java后端cors跨域设置白名单可以通过以下步骤实现: 1. 在web.xml文件中添加CorsFilter过滤器。 2. 在CorsFilter过滤器中设置允许跨域的域名白名单,可以使用通配符*表示允许所有域名跨域访问。 3. 在CorsFilter过滤器中设置允许跨域的请求方法,例如GET、POST等。 4. 在CorsFilter过滤器中设置允许跨域的请求头,例如Content-Type、Authorization等。 5. 在CorsFilter过滤器中设置允许跨域的响应头,例如Access-Control-Allow-Origin、Access-Control-Allow-Methods等。 具体实现可以参考以下代码: ``` public class CorsFilter implements Filter { private String allowOrigin; private String allowMethods; private String allowCredentials; private String allowHeaders; private String exposeHeaders; @Override public void init(FilterConfig filterConfig) throws ServletException { allowOrigin = filterConfig.getInitParameter("allowOrigin"); allowMethods = filterConfig.getInitParameter("allowMethods"); allowCredentials = filterConfig.getInitParameter("allowCredentials"); allowHeaders = filterConfig.getInitParameter("allowHeaders"); exposeHeaders = filterConfig.getInitParameter("exposeHeaders"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; HttpServletRequest request = (HttpServletRequest) servletRequest; if (StringUtils.isNotBlank(allowOrigin)) { response.setHeader("Access-Control-Allow-Origin", allowOrigin); } if (StringUtils.isNotBlank(allowMethods)) { response.setHeader("Access-Control-Allow-Methods", allowMethods); } if (StringUtils.isNotBlank(allowCredentials)) { response.setHeader("Access-Control-Allow-Credentials", allowCredentials); } if (StringUtils.isNotBlank(allowHeaders)) { response.setHeader("Access-Control-Allow-Headers", allowHeaders); } if (StringUtils.isNotBlank(exposeHeaders)) { response.setHeader("Access-Control-Expose-Headers", exposeHeaders); } filterChain.doFilter(request, response); } @Override public void destroy() { } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值