跨域过滤器org.apache.catalina.filters.CorsFilter源码核心点分析

本文深入解析了ApacheCatalina中的CORSFilter工作原理,重点介绍了如何通过switchcase处理不同类型的跨域请求,包括预检请求(PRE_FLIGHT)。文章详细阐述了预检请求的处理流程,强调了其在过滤器链中不继续传递的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 @Override
    public void doFilter(final ServletRequest servletRequest,
            final ServletResponse servletResponse, final FilterChain filterChain)
            throws IOException, ServletException {
        if (!(servletRequest instanceof HttpServletRequest) ||
                !(servletResponse instanceof HttpServletResponse)) {
            throw new ServletException(sm.getString("corsFilter.onlyHttp"));
        }

        // Safe to downcast at this point.
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // Determines the CORS request type.
        CorsFilter.CORSRequestType requestType = checkRequestType(request);

        // Adds CORS specific attributes to request.
        if (decorateRequest) {
            CorsFilter.decorateCORSProperties(request, requestType);
        }
        switch (requestType) {
        case SIMPLE:
            // Handles a Simple CORS request.
            this.handleSimpleCORS(request, response, filterChain);
            break;
        case ACTUAL:
            // Handles an Actual CORS request.
            this.handleSimpleCORS(request, response, filterChain);
            break;
        case PRE_FLIGHT:
            // Handles a Pre-flight CORS request.
            this.handlePreflightCORS(request, response, filterChain);
            break;
        case NOT_CORS:
            // Handles a Normal request that is not a cross-origin request.
            this.handleNonCORS(request, response, filterChain);
            break;
        default:
            // Handles a CORS request that violates specification.
            this.handleInvalidCORS(request, response, filterChain);
            break;
        }
    }

以上为org.apache.catalina.filters.CorsFilter核心代码,用switch case处理各种情况,其中在处理PRE_FLIGHT(刺探请求,比如跨域中的复杂请求,会先发一个options请求,这个请求就属于PRE_FLIGHT)时,处理完之后,不会再继续后续过滤器链:

/**
     * Handles CORS pre-flight request.
     *
     * @param request
     *            The {@link HttpServletRequest} object.
     * @param response
     *            The {@link HttpServletResponse} object.
     * @param filterChain
     *            The {@link FilterChain} object.
     * @throws IOException
     * @throws ServletException
     */
    protected void handlePreflightCORS(final HttpServletRequest request,
            final HttpServletResponse response, final FilterChain filterChain)
            throws IOException, ServletException {

        CORSRequestType requestType = checkRequestType(request);
        if (requestType != CORSRequestType.PRE_FLIGHT) {
            throw new IllegalArgumentException(sm.getString("corsFilter.wrongType1",
                    CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH)));
        }

        //此处省略了中间代码
        ...

        // Section 6.2.9
        response.addHeader(
                CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_METHODS,
                accessControlRequestMethod);

        // Section 6.2.10
        if ((allowedHttpHeaders != null) && (!allowedHttpHeaders.isEmpty())) {
            response.addHeader(
                    CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_HEADERS,
                    join(allowedHttpHeaders, ","));
        }

        // Do not forward the request down the filter chain.
        //到此方法就结束了
    }

由于不再走后续过滤器,再和其他过滤器进行整合时,需要注意处理逻辑,必要时请将org.apache.catalina.filters.CorsFilter放置于过滤器末端。

对于PRE_FLIGHT的解释,参考下边源码:

protected static enum CORSRequestType {
        /**
         * A simple HTTP request, i.e. it shouldn't be pre-flighted.
         */
        SIMPLE,
        /**
         * A HTTP request that needs to be pre-flighted.
         */
        ACTUAL,
        /**
         * A pre-flight CORS request, to get meta information, before a
         * non-simple HTTP request is sent.
         * 在发送简单请求前,为了获取meta信息而发送的预检请求(刺探)
         */
        PRE_FLIGHT,
        /**
         * Not a CORS request, but a normal request.
         */
        NOT_CORS,
        /**
         * An invalid CORS request, i.e. it qualifies to be a CORS request, but
         * fails to be a valid one.
         */
        INVALID_CORS
    }

 

`org.apache.catalina.filters.CorsFilter` 是Apache Tomcat中用于处理源资源共享(CORS)的一个过滤器CORS是一种网络技术,它允许一个上的网页去请求另一个上的资源,这通常用于Web API的场景。 `CorsFilter()` 是这个过滤器的一个构造函数,用于创建一个新的 `CorsFilter` 实例。而 `org.springframework.web.cors.UrlBasedCorsConfigurationSource` 是Spring框架提供的一个用于配置CORS的类,它可以根据URL路径来设置CORS策略。 当你看到 `CorsFilter()` 无法应用于 `UrlBasedCorsConfigurationSource` 的错误时,这意味着你在配置CORS时可能使用了错误的方式。在Spring框架中,通常不会直接使用 `CorsFilter` 的构造函数,而是通过Spring的配置方法来设置CORS。 例如,在Spring Security配置中,你可能会使用 `CorsConfiguration` 和 `UrlBasedCorsConfigurationSource` 来设置CORS策略,然后通过配置类或者Java配置代码将其应用到你的Spring应用中。以下是一个简化的例子: ```java @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } ``` 在这个例子中,`CorsFilter` 是通过 `UrlBasedCorsConfigurationSource` 来配置的,而不是直接通过 `CorsFilter()` 构造函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值