Java SpringBoot中如何拦截或禁用HTTP TRACE请求方法
问题场景
为了禁用不安全的HTTP方法,我最初实现了如下请求过滤器:
@Component public class MethodFilter extends OncePerRequestFilter { private final String[] allowedMethods = new String[]{"PUT", "POST", "GET", "OPTIONS"}; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (Arrays.stream(allowedMethods).noneMatch(x -> x.equals(request.getMethod()))) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } filterChain.doFilter(request, response); } }
该过滤器对除TRACE外的所有方法都可正常生效:TRACE请求不会触发该过滤器,响应体会返回所有请求头的回显内容,示例如下:
TRACE /error HTTP/1.1 my-header: test accept: */* host: localhost:8087 accept-encoding: gzip, deflate, br connection: keep-alive
其他不在允许列表中的方法都能正常返回预期的405错误,示例如下:
{ "timestamp": "2021-11-03T11:49:48.545+0000", "status": 405, "error": "Method Not Allowed", "message": "DELETE method is not allowed", "path": "/test" }
查阅官方文档可知,TRACE请求默认会直接发送到FrameworkServlet自行处理,不会进入自定义过滤器链路。我尝试设置配置项spring.mvc.dispatch-trace-request=true,却出现了两种响应拼接的异常,过滤器仍未被调用,异常响应示例如下:
{ "timestamp": "2021-11-03T11:49:48.545+0000", "status": 405, "error": "Method Not Allowed", "message": "TRACE method is not allowed", "path": "/test" }TRACE /error HTTP/1.1 my-header: test accept: */* host: localhost:8087 accept-encoding: gzip, deflate, br connection: keep-alive
我希望TRACE方法的响应格式和其他被禁用的方法保持一致,多次尝试后最终找到可行方案。
注:公开的Stack Overflow相关讨论帖中的解决方案均不生效。
可行解决方案
使用Spring MVC拦截器替代过滤器即可解决该问题,完整实现步骤如下:
- 实现自定义方法校验拦截器
@Component public class MethodInterceptor implements HandlerInterceptor { private final String[] allowedMethods = new String[]{"PUT", "POST", "GET", "OPTIONS"}; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (Arrays.stream(allowedMethods).noneMatch(x -> x.equals(request.getMethod()))) { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); response.setHeader("Allow", "PUT, POST, GET, OPTIONS"); response.setContentType("message/http"); response.getWriter().println(request.getMethod() + " method not allowed"); response.getWriter().flush(); return false; } return true; } }
- 注册拦截器到Spring MVC上下文
@Configuration public class InterceptorConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MethodInterceptor()); } }
- 开启TRACE请求分发配置
在项目配置文件(application.properties/application.yml)中添加如下配置:spring.mvc.dispatch-trace-request=true
该配置为必填项,开启后Spring MVC才会将TRACE请求分发到业务拦截器链路中
内容的提问来源于stack exchange,提问作者SpartanX1
相关产品推荐
相关产品推荐

