You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot应用配置*目标仅允许GET、POST HTTP方法实现方案

Spring Boot 全局限制仅开放GET/POST方法实现方案

常规Spring MVC层的拦截配置(包括HandlerInterceptor、@RequestMapping method属性限定、Spring Security路径拦截规则)只能覆盖DispatcherServlet处理的业务路径请求,无法修改内嵌Web容器对*通用目标路径OPTIONS请求的默认响应——这也是此前方案失效的核心原因:容器默认的DefaultServlet会提前拦截这类通配路径请求,直接返回内置的全量允许方法列表,请求根本不会进入Spring的处理链路。


方案1:高优先级全局Filter(全容器兼容,首选)

该方案不依赖特定内嵌容器实现(Tomcat/Jetty/Undertow均适用),通过最高优先级的Filter在请求进入容器默认处理逻辑前完成拦截,手动控制响应规则:

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalHttpMethodLimitFilter implements Filter {
    // 配置全局允许的HTTP方法
    private static final String ALLOWED_METHODS = "GET,POST";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;
        HttpServletResponse httpResp = (HttpServletResponse) response;
        String requestMethod = httpReq.getMethod();

        // 1. 专门处理针对*通配路径的OPTIONS请求,直接返回自定义Allow头
        if ("OPTIONS".equalsIgnoreCase(requestMethod) && "*".equals(httpReq.getRequestURI())) {
            httpResp.setHeader("Allow", ALLOWED_METHODS);
            httpResp.setStatus(HttpServletResponse.SC_OK);
            return;
        }

        // 2. 拦截所有非允许方法的请求,直接返回405状态码
        boolean isMethodAllowed = "GET".equalsIgnoreCase(requestMethod) || "POST".equalsIgnoreCase(requestMethod);
        // 若需要兼容HTTP协议默认的HEAD方法(HEAD为无响应体的GET请求,无额外安全风险),可放开下面这行注释
        // isMethodAllowed = isMethodAllowed || "HEAD".equalsIgnoreCase(requestMethod);
        if (!isMethodAllowed) {
            httpResp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            return;
        }

        chain.doFilter(request, response);
    }
}

如果项目集成了Spring Security,需要额外在Security配置中关闭默认的OPTIONS自动处理逻辑,避免配置被覆盖:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .cors(Customizer.withDefaults())
                // 关闭Security默认的OPTIONS请求自动响应逻辑
                .requestCache().disable()
                .authorizeHttpRequests(auth -> {
                    // 业务路径权限规则按实际需求配置即可
                    auth.anyRequest().authenticated();
                });
        return http.build();
    }
}

方案2:Tomcat原生配置(无额外Filter开销)

如果项目使用Spring Boot默认的Tomcat内嵌容器,可直接自定义Tomcat配置,修改DefaultServlet的初始化参数,从容器层面限制允许的方法:

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatHttpMethodConfig {
    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatMethodLimitCustomizer() {
        return factory -> factory.addContextCustomizers(context -> {
            // 配置Tomcat全局允许的HTTP方法
            context.setAllowSemicolonContent(false);
            // 给默认Servlet设置允许方法列表,替换默认返回的Allow头
            context.getServletRegistration("default").addInitParameter("allow", "GET,POST");
            // 禁用TRACE等危险方法
            context.setUseHttpOnly(true);
        });
    }
}

验证方式

配置完成后重启服务,用之前的测试命令验证即可:

  • 执行nikto扫描命令:nikto -ssl -h https://localhost:8181,扫描结果中允许的HTTP方法仅显示GET、POST,不会再出现PUT/DELETE等方法的风险提示
  • 执行curl测试命令:curl -k -i --request-target "*" -X OPTIONS https://localhost:8181,返回响应中Allow头的值为GET,POST,状态码为200
  • 发送PUT/DELETE等其他方法请求任意路径,均会返回405 Method Not Allowed响应。

补充说明:部分HTTP客户端和扫描工具会默认将HEAD方法识别为允许方法,该行为符合HTTP RFC规范——HEAD本质是不返回响应体的GET请求,服务端支持GET就必然支持HEAD,不存在文件写入、删除等安全风险。如果客户强制要求Allow头中不出现HEAD字段,删掉Filter代码中HEAD方法放行的注释逻辑即可。

内容的提问来源于stack exchange,提问作者Philippe MESMEUR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:33:29