【问题标题】:How can I have my Filter before a javax.websocket Upgrade如何在 javax.websocket 升级之前拥有我的过滤器
【发布时间】:2014-09-23 11:32:56
【问题描述】:

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

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

【问题讨论】:

    标签: jetty


    【解决方案1】:

    首先,ServletContextInitializer 没有排序,该功能不是 Servlet 规范的一部分。您无法完成问题的那部分。 (也许在 Servlet 规范的未来版本中)

    接下来,非常不鼓励过滤 WebSocket 升级请求,这会导致 WebSocket 出现大量问题。您必须非常小心不要执行以下任何操作。

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

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

    • request.getAttribute(字符串名称)
    • request.getContextPath()
    • request.getCookies()
    • request.getHeader(字符串名称)
    • request.getIntHeader(字符串名称)
    • 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 规范和容器,并在容器级别实现/配置安全性,这将始终在 websocket 或 servlet 或过滤器之前执行。从而完全放弃基于安全的过滤器。

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      相关资源
      最近更新 更多