Http 错误代码状态从 405 更改为 401(spring boot 2 和 jetty)

Http error code status changes from 405 to 401 (spring boot 2 and jetty)

感谢您花时间调查此问题。我一直在开发 spring boot 2 应用程序,并且添加了一个自定义过滤器(DisabledHttpMethodFilter extends OncePerRequestFilter implements Ordered)以不允许 TRACE 和 OPTIONS 方法调用。我抛出错误(SC_METHOD_NOT_ALLOWED = 405)。过滤器似乎在工作并且不允许 TRACE 和 OPTIONS 调用但是有一些问题并且 http 状态代码正在从 405 更改为 401。我已经多次调试这个问题并且找不到它背后的根本原因。 我附上调试的屏幕截图。处理程序和调度程序方法堆栈中的错误代码发生变化。

在下面的屏幕中,可以看到从过滤器 class 抛出状态代码 405。

没有中间件 filter/handler 造成任何伤害,直到 HttpChannel class 之前一切都很顺利。

从这个 class 代码到 ErrorHandler(我跳过了很多 classes 和它们的屏幕截图。只是想展示中间阶段。仍然是 405 代码)

然后在 handle/dispatch 方法之一中,它从 405 变为 401。

请让我知道哪里出了问题。我有一个并行应用程序,其中相同的过滤器工作正常。我已经并行调试了这两个应用程序,但我在方法堆栈中迷路了。再次感谢你。

如果您达到 org.springframework.boot.web.embedded.JettyEmbeddedErrorHandler,那么在达到该代码之前,请务必了解您的 回复已被重置

此行为符合 Servlet 规范。

这意味着所有响应 headers、缓冲区和值都重置为默认值(一个值得注意的例外是 java.servlet.http.Cookie objects 在响应中被跟踪)。

通用 Servlet and/or Jetty 建议。

首先,TRACE 在所有 WebApps 上默认被禁用,但这是 Spring,所有的赌注都没有了(因为它认为它比容器更了解)。

接下来,禁用 HTTP 方法是通过约束而不是过滤器在 Servlet 规范中完成的。 (就像禁用的 TRACE 方法一样)

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Disable TRACE</web-resource-name>
      <url-pattern>/</url-pattern>
      <http-method>TRACE</http-method>
    </web-resource-collection>
    <auth-constraint/>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Enable everything but TRACE</web-resource-name>
      <url-pattern>/</url-pattern>
      <http-method-omission>TRACE</http-method-omission>
    </web-resource-collection>
  </security-constraint>

给你的建议DisabledHttpMethodFilter

你的 DisabledHttpMethodFilter 应该避免使用 OncePerRequestFilter,它不适合终端行为(你不想在 Spring 中处理更多的东西)。由于使用 spring 过滤器作为基础,Spring 中的过滤器堆栈基本上会撤销您的努力。

Ordered 行为可以确保您的 Filter 在正确的位置,但即便如此最终也不是成功所必需的。

如果您的 DisabledHttpMethodFilter 使用 HttpServletResponse.sendError(),那么您应该确保在您的 spring 应用程序中对响应代码 405 进行自定义错误处理,该处理实际上什么都不做。 (以防止 spring 和码头破坏你的努力)

如果你的 DisabledHttpMethodFilter 使用 HttpServletResponse.setStatus() 并在不调用过滤器链的情况下返回,那么你就没有别的事可做(但是很容易得到额外的响应 headers 可能会与您的意图冲突。例如在不适当的状态代码响应中缓存 headers)

DisabledHttpMethodFilter 的更好方法是抛出一个自定义异常,比如 MethodDisabledException 和一个在 spring and/or Jetty 注册的自定义错误处理只是将状态代码设置为 405 的异常。这允许响应重置发生(一件好事!),并且它最大限度地减少其他 Spring 调度行为执行和更改您的意图。