【问题标题】:How to intercept/disable HTTP Trace Method in Java SpringBoot如何在 Java Spring Boot 中拦截/禁用 HTTP 跟踪方法
【发布时间】: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


    【解决方案1】:

    如果您尝试为其配置 Spring Security 会怎样... 手动写过滤器的方法,感觉有点低级……

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
         http
        .authorizeRequests()
           // You can actually disable other methods here as well
          .antMatchers(HttpMethod.TRACE,"/**").denyAll()
        .httpBasic();
    }
    

    如果这对你不起作用......根据它说的文档

    Note that HttpServlets default TRACE processing will be applied
    in any case if your controllers happen to not generate a response
    of content type 'message/http' (as required for a TRACE response)
    

    当您在过滤器中响应TRACE 请求时,为什么不尝试将内容类型标头设置为message/http

    另一个选项是在dispatcher servlet 中禁用此功能

    【讨论】:

    • 关于 Spring Security,想不用它。另外,我不想启用授权(anyMatchers 仅在此可用),因为身份验证是单独处理的。
    • 至于 message/http 内容类型,你说得对,文档确实说,但是我尝试将 response.setContentType 设置为此,但过滤器似乎从未被调用。
    • 如果我们试试这个呢? stackoverflow.com/a/54306649/2599899
    • 贴在问题的最后
    • 更新了我的回答。使用@Component
    猜你喜欢
    • 1970-01-01
    • 2016-05-10
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 2021-03-27
    • 1970-01-01
    • 2013-09-28
    相关资源
    最近更新 更多