Spring Web应用如何配置限制仅允许GET和POST两种HTTP方法
Spring Boot 仅允许GET/POST HTTP方法配置方案
针对安全扫描发现服务端默认开放PUT、DELETE、OPTIONS等冗余HTTP方法,存在文件篡改、删除风险的问题,可通过以下任意一种方案实现方法访问限制,最终仅对外暴露GET、POST接口。
方案1:Spring Security 拦截(生产环境推荐)
如果项目已引入Spring Security依赖,直接在安全过滤链中配置方法访问规则即可,该方案稳定性最高,适配所有Spring Boot 2.7+版本:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 按业务实际需求配置GET、POST请求的鉴权规则,以下示例为放行所有GET/POST请求 .requestMatchers(HttpMethod.GET, "/**").permitAll() .requestMatchers(HttpMethod.POST, "/**").permitAll() // 其余所有HTTP方法(PUT/DELETE/OPTIONS/PATCH/HEAD等)直接拒绝,返回405状态码 .anyRequest().denyAll() ) // 若不需要跨域支持直接关闭,避免框架自动返回允许所有方法的Allow响应头 .cors(cors -> cors.disable()) .csrf(csrf -> csrf.disable()); return http.build(); } }
如果业务需要保留跨域能力,不要直接关闭cors,在跨域配置项中明确setAllowedMethods为GET、POST即可。
方案2:无Spring Security依赖时,自定义Tomcat容器拦截
未引入Spring Security的项目,可以通过定制内置Tomcat连接器的请求拦截逻辑,在容器层直接过滤非法方法:
import org.apache.catalina.connector.Response; import org.apache.coyote.http11.Http11NioProtocol; 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; import org.springframework.http.HttpMethod; import java.util.Set; @Configuration public class TomcatMethodLimitConfig { private static final Set<String> ALLOWED_METHODS = Set.of( HttpMethod.GET.name(), HttpMethod.POST.name() ); @Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> methodLimitCustomizer() { return factory -> factory.addConnectorCustomizers(connector -> { Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); protocol.setRejectIllegalHeader(true); connector.addRequestInterceptor(request -> { String currentMethod = request.getMethod().toUpperCase(); if (!ALLOWED_METHODS.contains(currentMethod)) { Response response = request.getResponse(); response.setStatus(Response.SC_METHOD_NOT_ALLOWED); response.setHeader("Allow", String.join(", ", ALLOWED_METHODS)); response.setContentType("text/plain;charset=UTF-8"); response.getWriter().write("Method Not Allowed"); response.finishResponse(); } }); }); } }
方案3:Spring MVC 全局拦截器实现
也可以通过自定义MVC拦截器,在请求进入Controller层之前拦截非法HTTP方法:
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import java.util.Set; @Component public class MethodLimitInterceptor implements HandlerInterceptor { private static final Set<String> ALLOWED_METHODS = Set.of( HttpMethod.GET.name(), HttpMethod.POST.name() ); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String currentMethod = request.getMethod().toUpperCase(); if (!ALLOWED_METHODS.contains(currentMethod)) { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); response.setHeader("Allow", String.join(", ", ALLOWED_METHODS)); response.getWriter().write("Method Not Allowed"); return false; } return true; } } // 注册拦截器 @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private MethodLimitInterceptor methodLimitInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(methodLimitInterceptor).addPathPatterns("/**"); } }
配置验证
配置完成重启应用后,可通过curl命令或原nikto扫描命令验证效果:
# 测试PUT请求,预期返回405 Method Not Allowed curl -X PUT https://localhost:8181 -k -I # 测试DELETE请求,预期返回405 curl -X DELETE https://localhost:8181 -k -I # 测试OPTIONS请求,预期返回405 curl -X OPTIONS https://localhost:8181 -k -I
验证通过后,响应头中的Allow字段仅会展示GET, POST,nikto扫描不会再出现PUT、DELETE方法的风险提示。
注意事项
- 如果业务需要用HEAD方法做服务探活、健康检查,可在允许方法集合中添加
HttpMethod.HEAD.name(),该方法仅返回响应头,无业务安全风险- 不要直接删除Tomcat默认的DefaultServlet,否则会导致静态资源、默认错误页映射失效
- 若服务外层有Nginx、网关等代理层,也可直接在代理层配置HTTP方法拦截,实现多层防护
内容的提问来源于stack exchange,提问作者Philippe MESMEUR
相关产品推荐
相关产品推荐

