使用Jetty和JavaScript客户端设置安全的WebSocket服务器 [英] Setting up secure WebSocket server with Jetty and JavaScript client

查看:166
本文介绍了使用Jetty和JavaScript客户端设置安全的WebSocket服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Jetty设置安全的WebSocket服务器,如下所示:

I am trying to setup a secure WebSocket server with Jetty like the following:

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.server.WebSocketHandler;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;


public class WebSocketServer
{
    private Server server;
    private String host="localhost";
    private int port=8080;
    private String keyStorePath = "C:\\keystore";
    private String keyStorePassword="password";
    private String keyManagerPassword="password";
    private List<Handler> webSocketHandlerList = new ArrayList();
    MessageHandler messagehandler;

    public WebSocketServer()
    {
        System.out.println("WebSocketServer");

        server = new Server();

        // connector configuration
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(keyStorePath);
        sslContextFactory.setKeyStorePassword(keyStorePassword);
        sslContextFactory.setKeyManagerPassword(keyManagerPassword);
        SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString());
        HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory(new HttpConfiguration());
        ServerConnector sslConnector = new ServerConnector(server, sslConnectionFactory, httpConnectionFactory);
        sslConnector.setHost(host);
        sslConnector.setPort(port);
        server.addConnector(sslConnector);

        // handler configuration
        HandlerCollection handlerCollection = new HandlerCollection();
        handlerCollection.setHandlers(webSocketHandlerList.toArray(new Handler[0]));
        server.setHandler(handlerCollection);

        WebSocketHandler wsHandler = new WebSocketHandler() {
            @Override
            public void configure(WebSocketServletFactory webSocketServletFactory) {
                webSocketServletFactory.register(MyWebSocketHandler.class);
            }
        };
        ContextHandler wsContextHandler = new ContextHandler();
        wsContextHandler.setHandler(wsHandler);
        wsContextHandler.setContextPath("/");  // this context path doesn't work ftm
        webSocketHandlerList.add(wsHandler);

        messagehandler = new MessageHandler();
        new Thread(messagehandler).start();

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

创建密钥库文件时以下命令在jdk / bin文件夹中找到此处

The keystore file is created with the following command found here in the jdk/bin folder:

keytool.exe -keystore keystore -alias jetty -genkey -keyalg RSA

之后我将文件移到C目录中以方便路径使用。

After that I moved the file into the C directory for easy path usage.

使用此配置我的服务器似乎没有任何问题。所以我试图用我的网站连接到它:

With this configuration my server seems to start without any problems. So I am trying to connect to it with my website like this:

ws = new WebSocket("wss://localhost:8080/");

这根本不起作用。就像在这里写的 一样,我想我必须配置SSL证书。此外,为了创建服务器,我使用了这个教程对于Java客户端,他们实现了 truststore 。我是否必须为JavaScript做类似的事情?

This doesn't work at all. Like written here, I think I have to configure the SSL certificate. Furthermore, to create the server I used this tutorial and for the java client side they implement a truststore. Do I have to do something similar for JavaScript?

推荐答案

答案可能有点迟,但我已经做了它经过多次尝试后才能运作。

It might be a little late for an answer, but I've made it work after many attempts.

首先考虑一些一般因素:

A few general considerations first:


  • 作为遵循的一般规则(对node.js也有效),您必须首先使HTTPS工作以使WSS起作用。 WebSocket通过HTTP工作,因此如果您的服务器已正确配置HTTPS(或HTTP),则向其添加WebSocket将使WSS(或WS)正常工作。实际上,HTTPS / WSS和HTTP / WS都可以同时工作

  • As a general rule to follow (valid for node.js, too), you have to first make HTTPS work for WSS to work. WebSocket works over HTTP, so if your server has correctly configured HTTPS (or HTTP), then adding WebSocket to it will make WSS (or WS) work. Actually both HTTPS/WSS and HTTP/WS can work at the same time

证书非常重要,因为并非所有类型的证书都适用于Jetty(相同)对于node.js来说是正确的。因此,您必须生成Jetty将接受的证书。

Certificates are very important, as not all kinds of certificates work with Jetty (the same is true for node.js). So you have to generate the certificates that Jetty will accept.

使HTTPS工作对于自签名证书也很重要,因为您可能必须首先访问服务器通过HTTPS并在WSS可以工作之前添加异常(这可能取决于浏览器。)

Making HTTPS work is also important for self-signed certificates, as you might have to first access the server via HTTPS and add the exception before WSS can work (This might depend on the browser.)

需要考虑的另一件事是上下文路径需要是也正确设置。我通过为HTTP和WS提供单独的路径来实现它,例如HTTP(S)的 / hello / ws 用于WS(S)。可能有两个相同的上下文路径,但我没有调查那个

Another thing to consider is that the context paths need to be correctly setup, too. I've made it work by having separate paths for HTTP and WS, like /hello for HTTP(S) and /ws for WS(S). It might be possible to do it with the same context path for both, but I didn't investigate that yet

以下是我遵循的步骤。
我已经把工作示例放在了GitHub。

Below are the steps I followed. I've put a working example on GitHub.

1)使用这里

上面的链接有一个关于如何生成正确的自签名证书的示例。 (如果你有CA签名的证书,我认为程序有些不同。)

The above link has an example on how to generate correct self-signed certificates. (If you have CA-signed certificates, the procedure is somewhat different, I think.)

为了便于访问,我在这里粘贴命令。请注意,每当被要求时,请始终提供相同的密码(包括最后一个步骤,当您输入的密码将以明文显示在屏幕上时)。

I'm pasting the commands here for ease of access. Please pay attention to always give the same password whenever asked (including one of the final steps, when the password you type will appear in clear text on the screen).

openssl genrsa -aes256 -out jetty.key
openssl req -new -x509 -key jetty.key -out jetty.crt
keytool -keystore keystore -import -alias jetty -file jetty.crt -trustcacerts
openssl req -new -key jetty.key -out jetty.csr
openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12
keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore

2)在Jetty中拥有正确的HTTPS代码。

2) Have the correct code for HTTPS in Jetty.

网上有一些资源显示如何使用Jetty进行HTTPS,但对我来说只有一个工作,它是这里

There are some resources on the web that show how to do HTTPS with Jetty, but for me only one worked, and it is here.

3)有合作用于处理上下文的正确代码。

3) Have the correct code for handling contexts.

这个很难 - Jetty文档页面中的示例代码对我不起作用。
有效的是这个。本教程还启发了我,如果我尝试为HTTP和WS使用相同的路径,我可能会遇到冲突。

This one was tough - the example code from the Jetty documentation page did not work for me. What worked was this. This tutorial also enlightened me on the fact that I might have conflicts if I try to use the same path for HTTP and WS.

4)最后,拥有正确的代码WebSocket

4) Finally, have the correct code for WebSocket

我找到了正确的WebSocket代码这里。我们需要的是 native-jetty-websocket-example

I've found correct WebSocket code here. The one that has what we need is native-jetty-websocket-example.

这篇关于使用Jetty和JavaScript客户端设置安全的WebSocket服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆