【发布时间】:2021-11-03 12:01:10
【问题描述】:
为了禁用不安全的 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 /error HTTP/1.1
my-header: test
accept: */*
host: localhost:8087
accept-encoding: gzip, deflate, br
connection: keep-alive
对于不在列表中的所有其他方法,我得到了预期的结果
{
"timestamp": "2021-11-03T11:49:48.545+0000",
"status": 405,
"error": "Method Not Allowed",
"message": "DELETE method is not allowed",
"path": "/test"
}
参考doc 似乎,跟踪请求被发送到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 响应与其他请求相同?
注意:thread 中的解决方案对我不起作用。
编辑: 找到了解决方案。拦截器代替过滤器来解决问题
@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;
}
}
并通过配置文件添加拦截器
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MethodInterceptor());
}
}
这个需要和spring.mvc.dispatch-trace-request=true配合使用
【问题讨论】:
标签: java spring spring-boot http interceptor