Search code examples
javasslwebsocketembedded-jettyjetty-9

Cannot connect to secure Websocket running on Jetty


I have the following code which should setup a secure websocket endpoint in a stand alone Java application (jnlp triggered) and allow me to connect from a client (Javascript in the browser) with the url: ws://localhost:8444/echo

The server starts up without errors, but I cannot connect:

WebSocket connection to 'wss://localhost:8444/echo' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

    server = new Server();

    SslContextFactory contextFactory = new SslContextFactory();
    contextFactory.setKeyStorePath("/path/keys/keystore.jks");
    contextFactory.setKeyStorePassword("changeit");
    SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(contextFactory, org.eclipse.jetty.http.HttpVersion.HTTP_1_1.toString());

    ServerConnector connector = new ServerConnector(server, sslConnectionFactory);
    connector.setPort(8444);

    ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    contextHandler.setContextPath("/");
    HandlerCollection hc = new HandlerCollection();
    hc.addHandler(contextHandler);
    server.setHandler(contextHandler);

    server.addConnector(connector);

    // Add websocket servlet
    ServletHolder wsHolder = new ServletHolder("echo",new EchoSocketServlet());
    contextHandler.addServlet(wsHolder,"/echo");

    try
    {
        server.start();
        server.join();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

If anyone can spot an obvious error in the above, some feedback would be appreciated. Also, I can successfully connect to the above when I remove the SslConnectionFactory and connect using non SSL Websocket URL (ws://).


Solution

  • Finally got it working with a lot of trial and error, some pain and a little help from this guy: https://stackoverflow.com/a/37882046/2288004

    For anyone who think they might be helped out by this, I updated the server code as below and went to the bother of creating a self signed certificate: Also, the final pièce de résistance (when using a self signed (untrusted) cert) is to browse to the secure url in your browser of choice, and get prompted such that you can add an exception. If you don't, it will NEVER work!!

        final int port = 5040;
        final int sslPort = 8442;
    
        server = new Server(port);
    
        SslContextFactory contextFactory = new SslContextFactory();
        contextFactory.setKeyStorePath("/Users/me/keystore");
        contextFactory.setKeyStorePassword("password");
        SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(contextFactory, org.eclipse.jetty.http.HttpVersion.HTTP_1_1.toString());
    
        HttpConfiguration config = new HttpConfiguration();
        config.setSecureScheme("https");
        config.setSecurePort(sslPort);
        config.setOutputBufferSize(32786);
        config.setRequestHeaderSize(8192);
        config.setResponseHeaderSize(8192);
        HttpConfiguration sslConfiguration = new HttpConfiguration(config);
        sslConfiguration.addCustomizer(new SecureRequestCustomizer());
        HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory(sslConfiguration);
    
        ServerConnector connector = new ServerConnector(server, sslConnectionFactory, httpConnectionFactory);
    
        connector.setPort(sslPort);
        server.addConnector(connector);
    
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
    
        try
        {
            // Add websocket servlet
            ServletHolder wsHolder = new ServletHolder("ws-echo", new EchoSocketServlet());
            context.addServlet(wsHolder,"/echo");
    
            server.setHandler(context);
    
            server.start();
            server.dump(System.err);
            server.join();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }