如何使用带有 SSL 的 Spring WebSocketClient? [英] How to use Spring WebSocketClient with SSL?
问题描述
我用我的 websocket 客户端连接到非 SSL 端点,没有任何问题.但是我找不到如何连接到 wss (SSL) 端点的任何方法.我在哪里可以定义 SSL 工厂等.似乎没有对象具有相关的 set 方法.
I connect with my websocket client to non-SSL endpoint without any problem. But I cannot find any way how to connect to wss (SSL) endpoint. Where can I define the SSL factory etc. No object seem to have related set method.
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);
我正在使用 wss://url,另一方面我有一个带有自签名证书的服务器.但是,这段代码在连接时没有抛出任何异常,而是没有建立会话.
I am using wss:// url and on the other side I have a server with self-signed certificate. However, this code does not throw any exception while connecting, but the session is not established.
编辑:启用 Web 跟踪后.* 我收到一个标准错误,
EDIT: After enabling tracing for web.* I got a standard error, with
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
使用自签名证书连接到服务器时会发生这种情况.但是,对于 RestTemplate,我已经使用此代码更新了 SSLContext,并且 REST 调用现在很好,但我不知道为什么,StandardWebSocketClient 忽略了 SSLContext.为什么?
It occurs when connecting to server with self-signed certificate. However, for RestTemplate I already updated SSLContext with this code and REST calls are fine now, but I do not know why, StandardWebSocketClient is IGNORING the SSLContext. Why?
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);
更新:不幸的是,我没有使用自定义信任库来做到这一点.我用 InstallCert.java 安装了证书.
UPDATE: Unfortunately, I did not managed to do this with custom truststore. I installed the certificate with InstallCert.java.
推荐答案
我认为每个 websocket 容器实现都提供了实现此目的的方法.您必须使用 StandardWebSocketClient .setUserProperties
设置此配置.所有这些属性都是在客户端使用的 ClientEndpointConfig
内部设置的.
I think that each websocket container implementation provides ways to do this.
You have to set this configuration using the StandardWebSocketClient .setUserProperties
. All those properties are internally set in the ClientEndpointConfig
used by the client.
以下是 Tomcat 作为提供者的示例:
Here's an example with Tomcat as a provider:
StandardWebSocketClient wsClient = //...;
SSLContext sslContext = //...;
wsClient.setUserProperties(WsWebSocketContainer.SSL_CONTEXT_PROPERTY, sslContext);
在任何情况下,您都应该参考您的提供商参考文档以了解您应该使用哪些配置密钥.
In any case you should refer to your provider reference documentation to know which configuration keys you should use.
这篇关于如何使用带有 SSL 的 Spring WebSocketClient?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!