H.e.l.l.o社区,我希望有人可以帮助我...我正在使用apache tomcat 8.0.0-RC5和JSR-356 web socket API ... 我有两个问题:
1)是否可以在@OnOpen方法上获取客户端IP?
2)是否可以获得连接的起源???
我按照websocket示例附带了tomcat的分发,我无法找到答案....我的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
}
}
答案 0 :(得分:0)
重复我已经在Tomcat用户邮件列表上给你的答案......
客户端IP。不可以。通常这种类型的信息可以在握手时获得 它发生在OnOpen之前,但客户端IP不是其中之一 信息曝光。你可能会更好地阻止这些早期的例如用iptables或类似的东西。
起源。 ServerEndpointConfig.Configurator.checkOrigin(String)
您需要自定义配置程序。请记住,恶意客户端可以伪造原始标头。
答案 1 :(得分: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)