如何将SpringWebSocketClient与SSL一起使用?

如何将SpringWebSocketClient与SSL一起使用?,spring,websocket,spring-boot,spring-websocket,Spring,Websocket,Spring Boot,Spring Websocket,我将websocket客户端连接到非SSL端点,没有任何问题。但我找不到任何方法来连接wss(SSL)端点。在哪里可以定义SSL工厂等。似乎没有对象具有相关的set方法 WebSocketClient transport = new StandardWebSocketClient(); WebSocketStompClient stompClient = new WebSocketStompClient(transport); stompClient.setMessageConverter(ne

我将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);
我使用的是wss://url,另一方面,我有一个具有自签名证书的服务器。但是,此代码在连接时不会引发任何异常,但会话未建立

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

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
使用自签名证书连接到服务器时发生此错误。但是,对于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);

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

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

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

StandardWebSocketClient wsClient = //...;
SSLContext sslContext = //...;
wsClient.setUserProperties(WsWebSocketContainer.SSL_CONTEXT_PROPERTY, sslContext);

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

您知道Tyrus的此设置吗?我最终将自签名证书导入密钥库并使用了它。digz6666,您能告诉我-您是如何做到的吗?是否有任何方法可以禁用tomcat的主机名验证?我没有找到任何例子。@niegus这是一个新问题的素材。你能问一个吗?