2

您好社区,我希望有人可以帮助我...我正在使用 apache tomcat 8.0.0-RC5 和 JSR-356 web socket API ...我有两个问题:

1)是否可以通过@OnOpen 方法获取客户端IP?

2)是否有可能获得连接的来源???

我遵循了tomcat发行版附带的websocket示例,但我找不到答案....我的java类基本上如下

@ServerEndpoint(value = "/data.socket")
public class MyWebSocket {
    @OnOpen
    public void onOpen(Session session) {
        // Here is where i need the origin and remote client address
    }

    @OnClose
    public void onClose() {
        // disconnection handling
    }

    @OnMessage
    public void onMessage(String message) {
        // message handling
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        // Error handling
    }
}
4

2 回答 2

0

重复我已经在 Tomcat 用户邮件列表中给你的答案......

客户端 IP。不会。通常此类信息在 OnOpen 之前发生的握手时可用,但客户端 IP 不是公开的信息之一。你可能会更好地阻止这些,例如使用 iptables 或类似的。

起源。ServerEndpointConfig.Configurator.checkOrigin(String)您将需要一个自定义配置器。请记住,恶意客户端可以伪造原始标头。

于 2013-10-28T09:14:52.420 回答
0

我知道这个问题很老,但以防其他人在网络搜索中找到它:

是的,有一个简单的解决方法。Servlet 可以接收和转发 WebSocket 升级请求。诀窍是获取客户端 IP 地址并将其作为参数公开。

这是您的 servlet 代码:

@WebServlet("/myExternalEntryPoint")
public class WebSocketServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        var dispatcher = getServletContext().getRequestDispatcher("/myInternalEntryPoint");
        var requestWrapper = new MyRequestWrapper(request);
        dispatcher.forward(requestWrapper, response);
    }
}

这是 MyRequestWrapper:

class MyRequestWrapper extends HttpServletRequestWrapper {
    public RequestWrapper(HttpServletRequest request) {
        super(request);
    }

    public Map<String, String[]> getParameterMap() {
        return Collections.singletonMap("remoteAddr", new String[] {getRequest().getRemoteAddr()});
    }
}

现在在您的 WebSocket 实现中,您将能够通过 javax.websocket.Session.getRequestParameterMap() 获取 remoteAddr。

自然,如果您的原始请求包含您关心的参数,您将需要创建一个包含这些参数的映射。此外,我建议您附加一个单独的秘密参数并在您的 WebSocket 代码中检查它,以防止任何人直接访问内部入口点。

我发现这是可能的,因为 Tomcat 源代码 (WsFilter.java) 中有这样深思熟虑的评论:

// No endpoint registered for the requested path. Let the
// application handle it (it might redirect or forward for example)
于 2020-08-05T21:26:53.563 回答