如何在javax.websocket升级之前安装我的过滤器

时间:2014-09-23 11:32:57

标签: jetty

我想写自己的" ServletContainerInitializer"将我的本地过滤器添加到ServletContext。我还想管理ServletContainerInitializer调用的顺序,以便在websocket升级过滤器之前,我的本地过滤器将被请求注册并被请求命中。

我想知道如何初始化我的本地ServletContainerInitializer?

1 个答案:

答案 0 :(得分:0)

首先,ServletContextInitializer未被排序,该功能不属于Servlet规范。你无法完成问题的这一部分。 (可能在Servlet规范的未来版本中)

接下来,强烈建议不要过滤WebSocket升级请求,这是WebSocket中出现大量问题的原因。您必须非常小心才能执行以下任何操作。

  • 访问Response对象上的任何内容
  • 不包装请求或响应对象
  • 不要访问请求输入流或阅读器
  • 不访问Response输出流或编写器
  • 不添加标题
  • 不要更改标题
  • 不要访问请求HttpSession
  • 不访问请求用户主体
  • 不访问请求身份验证/授权方法
  • 不访问请求部分(multipart / form-data)
  • 不访问请求参数
  • 不要访问ServletContext
  • 请勿访问request.getScheme或isSecure
  • 不要从请求中删除内容(属性,标题,参数等)

简而言之,您可以做的唯一安全的事情是

  • request.getAttribute(String name)
  • request.getContextPath()
  • request.getCookies()
  • request.getHeader(String name)
  • request.getIntHeader(String name)
  • request.getLocalName()
  • request.getLocalPort()
  • request.getPathInfo()
  • request.getPathTranslated()
  • request.getQueryString()
  • request.getRemoteAddr()
  • request.getRemotePort()
  • request.getRequestURI()
  • request.getRequestURL()
  • request.getServerName()
  • request.getServerPort()

由于请求或响应对象上的所有其他访问都将更改请求的状态并阻止升级。

Jetty拥有WebSocketUpgradeFilter的事实只是我们对JSR-356(又名javax.websocket)规范实现的选择。它由服务器端ServletContextInitializeris forced to be first, always添加。

在实践中,您应该期望在Servlet处理之前进行升级(这包括过滤器),因为这是规范的编写方式。有open bugs against the spec about how interactions with filters and whatnot should be treated,但这些目前尚未得到答复,并且已经为未来版本的javax.websocket规范进行了大量安排。

Jetty的未来版本可能会从使用过滤器变为使用在路径映射级别合作的内部内容,将Servlet规范和WebSocket规范中的逻辑合并为一组新的规则。

由于这个问题经常出现,我已经勾选了社区wiki标志。

问题的首要原因是因为项目中的过滤器内置了一些身份验证或授权逻辑。

如果是这种情况,您有2个选项。

  1. 将身份验证和/或授权逻辑重构为独立的类,与您的过滤器无关。

    构建一个新的Filter和一个新的ServerEndpointConfig.Configurator,它使用现在常用的逻辑来完成您需要的最终结果。请注意,在潜在的WebSocket升级下,您无权访问整个HttpServletRequest对象,您只能访问HandshakeRequest对象内容。 (你现在可以看到限制)

  2. 正确使用Servlet规范和容器,并在容器级别实现/配置Security,它将始终在websocket或servlet或过滤器之前执行。因此完全放弃基于安全性的过滤器。