如何使用带有 SSL 的 Spring WebSocketClient?

Mej*_*jmo 6 spring websocket spring-boot spring-websocket

我用我的 websocket 客户端连接到非 SSL 端点,没有任何问题。但是我找不到如何连接到 wss (SSL) 端点的任何方法。我在哪里可以定义 SSL 工厂等。似乎没有对象具有相关的 set 方法。

WebSocketClient transport = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(transport);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
String url = cfg.getWebsocketEndpoint();
StompSessionHandler handler = new MySessionHandler();
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
stompClient.connect(url, handler);
Run Code Online (Sandbox Code Playgroud)

我正在使用 wss:// url,另一方面我有一个带有自签名证书的服务器。但是,此代码在连接时不会抛出任何异常,但未建立会话。

编辑:启用 web 跟踪后。* 我得到一个标准错误,与

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Run Code Online (Sandbox Code Playgroud)

它在使用自签名证书连接到服务器时发生。但是,对于 RestTemplate,我已经使用此代码更新了 SSLContext,并且 REST 调用现在很好,但我不知道为什么,StandardWebSocketClient 忽略了 SSLContext。为什么?

    String keystoreType = "JKS";
    InputStream keystoreLocation = new FileInputStream("src/main/resources/aaa.jks");
    char [] keystorePassword = "zzz".toCharArray();
    char [] keyPassword = "zzz".toCharArray();

    KeyStore keystore = KeyStore.getInstance(keystoreType);
    keystore.load(keystoreLocation, keystorePassword);
    KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmfactory.init(keystore, keyPassword);

    InputStream truststoreLocation = new FileInputStream("src/main/resources/aaa.jks");
    char [] truststorePassword = "zzz".toCharArray();
    String truststoreType = "JKS";

    KeyStore truststore = KeyStore.getInstance(truststoreType);
    truststore.load(truststoreLocation, truststorePassword);
    TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmfactory.init(truststore);

    KeyManager[] keymanagers = kmfactory.getKeyManagers();
    TrustManager[] trustmanagers =  tmfactory.getTrustManagers();

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keymanagers, trustmanagers, new SecureRandom());
    SSLContext.setDefault(sslContext);
Run Code Online (Sandbox Code Playgroud)

更新:不幸的是,我没有设法使用自定义信任库来做到这一点。我使用 InstallCert.java 安装了证书。

Bri*_*zel 4

我认为每个 websocket 容器实现都提供了执行此操作的方法。您必须使用 来设置此配置StandardWebSocketClient .setUserProperties。所有这些属性都是在ClientEndpointConfig客户端使用时内部设置的。

下面是一个使用 Tomcat 作为提供者的示例:

StandardWebSocketClient wsClient = //...;
SSLContext sslContext = //...;
wsClient.setUserProperties(WsWebSocketContainer.SSL_CONTEXT_PROPERTY, sslContext);
Run Code Online (Sandbox Code Playgroud)

在任何情况下,您都应该参考提供商的参考文档来了解应该使用哪些配置密钥。