apache tomcat 8 websocket起源和客户端地址

时间:2013-10-27 21:51:00

标签: java websocket tomcat8

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
    }
}

2 个答案:

答案 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)