如何使用带有 SSL 的 Spring WebSocketClient? [英] How to use Spring WebSocketClient with SSL?

查看:104
本文介绍了如何使用带有 SSL 的 Spring WebSocketClient?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用我的 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屋!

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