它来自Jetty-9.2.2 中过滤器和servlet的订购
如前所述"将安全逻辑拆分为一个独立的类,Servlet筛选器和自定义javax.websocket.server.ServerEndpointConfig.Configurator可以使用该类。"
我不知道如何实现这一点?有人能解释一下吗?
HTTP升级(又名websocket)请求到达,会发生什么?
-
容器看到它有各种各样的头,表明它是websocket的升级请求。
- 请求方法是
GET
吗 Upgrade
标头值是WebSocket
吗Sec-WebSocket-Key
标头值是否存在且有效Sec-WebSocket-Version
标头值是否存在且有效
- 请求方法是
-
容器尝试查找某个内容是否映射到该传入请求(使用servlet路径映射规则和javax.websocket-uri模板路径映射规则的组合)。
-
根据上述规则发现注册的端点后,必须对其进行初始化和配置,然后才能将其视为打开。
-
使用该端点的
ServerEndpointConfig
(所有端点都注册了此类,有些是默认值,有些是根据注释计算的,有些是通过ServerContainer.addEndpoint(ServerEndpointConfig)
方法提供的 -
以下顺序用于初始化websocket端点
- 容器建立代表传入原始升级请求的
HandshakeRequest
和HandshakeResponse
对象 - 容器从
ServerEndpointConfig.getConfigurator()
获得一个Configurator
- 容器调用
Configurator.modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response)
- 容器调用
Configurator.checkOrigin(String origin)
-如果失败,则返回立即错误403 Forbidden - 容器调用
Configurator.getNegotiatedSubprotocol(List<String> supported, List<String> requested)
-如果提供了子协议,它将用于WebSocket升级响应标头Sec-WebSocket-Protocol
- 容器调用
Configurator.getNegotiatedExtensions(List<Extension> installed, List<Extension> requested)
-返回的值用于WebSocket升级响应标头Sec-WebSocket-Extensions
- 容器使用创建
ServerEndpointConfig
时使用的端点类参数调用Configurator.getEndpointInstance(Class<T> endpointClass)
- 此时,创建了
Endpoint
+Session
,并打开了websocket
- 容器建立代表传入原始升级请求的
如果在任何时候您不希望升级此请求,只需从getEndpointInstance
类抛出一个异常即可。我推荐java.lang.InstantiationException
。这将导致Jetty不执行升级并将请求发送到servlet处理链。
但是,请注意,您在Configurator中对http响应的选择非常有限(根据JSR-356/javax.websocket规范,您的选择是未定义的)。