根据Tomcat开发人员的介绍,@ mark-thomas客户端IP 不会 通过JSR-356公开,因此无法使用纯JSR-356 API-
s实现此类功能。
您必须使用一个相当丑陋的技巧来解决该标准的局限性。
需要做的事情归结为:
- 在初始请求时(在websocket握手之前)为每个用户生成一个包含其IP的令牌
- 向下传递令牌,直到令牌到达端点实现
至少有两个hacky选项可以实现这一目标。
使用HttpSession- 使用侦听传入的HTTP请求
ServletRequestListener
- 调用
request.getSession()
传入请求以确保它具有会话并将客户端IP存储为会话属性。 - 使用方法创建一个
ServerEndpointConfig.Configurator
从中提取客户端IPHandshakeRequest#getHttpSession
并将其附加EndpointConfig
为用户属性的modifyHandshake
。 - 从
EndpointConfig
用户属性获取客户端IP ,将其存储在map或其他内容中,如果每个IP的会话数超过阈值,则触发清除逻辑。
您也可以使用
@WebFilter代替
ServletRequestListener
请注意,除非您的应用程序已经使用会话(例如出于身份验证目的),否则此选项可能会占用大量资源。
将IP作为加密令牌传递给URL- 创建附加到非websocket入口点的servlet或过滤器。例如
/mychat
- 获取客户端IP,使用随机盐和密钥对其进行加密以生成令牌。
- 用于
ServletRequest#getRequestDispatcher
将请求转发给/mychat/TOKEN
- 配置您的端点以使用路径参数,例如
@ServerEndpoint("/mychat/{token}")
- 从中提取令牌
@PathParam
并解密以获取客户端IP。将其存储在map或其他内容中,如果每个IP的会话数超过阈值,则触发清除逻辑。
为了简化安装,您可能希望在应用程序启动时生成加密密钥。
请注意,即使您正在执行客户端不可见的内部调度,也需要对IP进行加密。没有什么可以阻止攻击者
/mychat/2.3.4.5直接连接,从而欺骗了未经加密的客户端IP。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)