如何在Java SpringBoot中拦截/禁用HTTP跟踪方法

sg24os4d  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(278)

为了禁用不安全的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"
}

参考文档,跟踪请求被发送到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

我的问题是我如何才能使跟踪响应与其他请求相同?
注意:这个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结合使用

xhv8bpkk

xhv8bpkk1#

如果你试着为它配置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中禁用此选项

hgb9j2n6

hgb9j2n62#

默认情况下,TRACE目前是不允许的,至少在Spring-Boot 3.1中是这样,因为默认防火墙WebSecurity使用StrictFirewall,它允许方法DELETE,GET,HEAD,OPTIONS,PATCH,POST和PUT(https://github.com/spring-projects/spring-security/blob/492 bde 7808462 dac 36 b399531 f45 a297 bc 212 d 69/web/src/main/java/org/springframework/security/web/firewall/StrictHttpFirewall.java#L562)
这可以很容易地调整:

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    StrictHttpFirewall strictHttpFirewall = new StrictHttpFirewall();
    strictHttpFirewall.setAllowedHttpMethods(List.of(HttpMethod.GET.name(), HttpMethod.POST.name()))
    return (web) -> web.httpFirewall(strictHttpFirewall);
}

相关问题