對於這個問題,我準備了一個測試項目WssEmbedded,它在localhost:8080
和localhost:8443
上偵聽傳入的WebSocket連接。嵌入式Jetty中的SSL上的WebSocket 9
在MyHandler I類創建2個連接器用於此目的:
public class MyHandler extends WebSocketHandler {
@Override
public void configure(WebSocketServletFactory factory) {
factory.register(MyListener.class);
}
public static void main(String[] args) throws Exception {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("keystore.jks");
sslContextFactory.setKeyStorePassword("OBF:1l1a1s3g1yf41xtv20731xtn1yf21s3m1kxs");
Server server = new Server();
server.setHandler(new MyHandler());
ServerConnector wsConnector = new ServerConnector(server);
wsConnector.setHost("127.0.0.1");
wsConnector.setPort(8080);
server.addConnector(wsConnector);
ServerConnector wssConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()));
wssConnector.setHost("127.0.0.1");
wssConnector.setPort(8443);
server.addConnector(wssConnector);
server.start();
server.join();
}
}
我添加了一個密鑰/證書對來keystore.jks
與:
keytool -genkey -alias key1 -keyalg RSA -keypass password1 -keystore keystore.jks -storepass password1
服務器啓動沒有問題:
2016-06-22 13:34:45.254:INFO::main: Logging initialized @641ms
2016-06-22 13:34:45.404:INFO:oejs.Server:main: jetty-9.3.9.v20160517
2016-06-22 13:34:45.544:INFO:oejs.AbstractConnector:main: Started [email protected]{HTTP/1.1,[http/1.1]}{127.0.0.1:8080}
2016-06-22 13:34:45.594:INFO:oejus.SslContextFactory:main: [email protected](key1,h=[],w=[]) for [email protected](file:///C:/Users/user1/jetty-newbie/WssEmbedded/keystore.jks,null)
2016-06-22 13:34:46.084:INFO:oejs.AbstractConnector:main: Started [email protected]{SSL,[ssl]}{127.0.0.1:8443}
2016-06-22 13:34:46.084:INFO:oejs.Server:main: Started @1476ms
然後,我已經準備了一個簡單的WssClient項目測試上述服務器:
public static void main(String[] args) {
final String WS_URL = "ws://127.0.0.1:8080";
MyListener socket = new MyListener("Hello world");
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true);
WebSocketClient client = new WebSocketClient(sslContextFactory);
try {
client.start();
URI uri = new URI(WS_URL);
ClientUpgradeRequest cur = new ClientUpgradeRequest();
client.connect(socket, uri, cur);
socket.awaitClose(5, TimeUnit.SECONDS);
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客戶運作良好,並打印:
2016-06-22 13:36:06.130:INFO::main: Logging initialized @205ms
onWebSocketConnect: /127.0.0.1:8080
REQUEST:
Hello world
RESPONSE:
Hello /127.0.0.1:58518
onWebSocketClose: 1000 null
服務器運作良好,並打印:
2016-06-22 13:35:54.057:INFO:daw.MyListener:qtp1597462040-19: onWebSocketConnect: /127.0.0.1:58511
2016-06-22 13:35:54.097:INFO:daw.MyListener:qtp1597462040-14: onWebSocketText: Hello world
2016-06-22 13:35:54.107:INFO:daw.MyListener:qtp1597462040-13: onWebSocketClose: 1000 - null
但是,當我更改爲WS_URL = "wss://127.0.0.1:8443"
時,它將失敗:
2016-06-22 13:36:29.063:INFO::main: Logging initialized @208ms
onWebSocketError: java.nio.channels.ClosedChannelException
請問我在這裏錯過了什麼?如何調試呢?
UPDATE:
思考這個問題可能是上面使用的自簽名證書,我已經採取了Thawte的證書有效期爲3年,我的Web域slova.de
和www.slova.de
(它們指向不同的IP地址!),並使用Oracle jdk1.8.0_91-1.8.0_91-fcs.x86_64進口它在CentOS Linux的7成密鑰庫:
# keytool -importcert -file /etc/pki/tls/certs/slova.de.crt -keystore keystore.jks -storepass password1
Owner: CN=slova.de
Issuer: CN=thawte DV SSL SHA256 CA, OU=Domain Validated SSL, O="thawte, Inc.", C=US
Serial number: 9354a665699cafbfa7875490d5a9894
Valid from: Mon Apr 04 02:00:00 CEST 2016 until: Fri Apr 05 01:59:59 CEST 2019
Certificate fingerprints:
MD5: 33:BB:62:8A:09:24:11:0F:C9:40:AA:68:F4:CD:2A:B7
SHA1: 52:E2:B6:79:55:F4:FE:05:0D:2E:7C:18:78:58:22:16:ED:28:4F:B6
SHA256: A3:D3:83:4E:99:01:BF:AE:FB:EB:59:40:23:74:1D:28:93:4B:20:15:1D:E1:AC:1A:97:31:C6:0C:9B:E1:2D:03
Signature algorithm name: SHA256withRSA
Version: 3
正如你所看到的,我現在有一個可信的證書有:
# keytool -list -keystore keystore.jks -storepass password1
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 2 entries
key1, Jun 22, 2016, PrivateKeyEntry,
Certificate fingerprint (SHA1): 8F:7D:8E:E0:8F:9E:39:A1:0C:23:D3:FF:4B:47:F5:0D:BA:EC:EE:F3
mykey, Jun 22, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 52:E2:B6:79:55:F4:FE:05:0D:2E:7C:18:78:58:22:16:ED:28:4F:B6
然後我就開始在www.slova.de:8443
的WssEmbedded程序(在我的Linux服務器是從slova.de
Apache在其上運行不同的IP地址):
# java -classpath $CPATHS de.afarber.wssembedded.MyHandler 144.76.184.154:8443
2016-06-22 19:45:21.093:INFO::main: Logging initialized @73ms
2016-06-22 19:45:21.144:INFO:oejs.Server:main: jetty-9.3.9.v20160517
2016-06-22 19:45:21.167:INFO:oejs.AbstractConnector:main: Started [email protected]{HTTP/1.1,[http/1.1]}{www.slova.de:8080}
2016-06-22 19:45:21.188:INFO:oejus.SslContextFactory:main: [email protected](key1,h=[],w=[]) for [email protected](file:///usr/share/java/words/keystore.jks,null)
2016-06-22 19:45:21.189:INFO:oejus.SslContextFactory:main: [email protected](mykey,h=[slova.de, www.slova.de],w=[]) for [email protected](file:///usr/share/java/words/keystore.jks,null)
2016-06-22 19:45:21.327:INFO:oejs.AbstractConnector:main: Started [email protected]{SSL,[ssl]}{www.slova.de:8443}
2016-06-22 19:45:21.327:INFO:oejs.Server:main: Started @309ms
然後我在運行WssClient對wss://www.slova.de:8443
NetBeans在我的Macbook上:
Executing command line: /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=56634 -classpath /Users/afarber/src/jetty-newbie/WssClient/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar de.afarber.wssclient.Main
2016-06-22 19:45:31.718:INFO::main: Logging initialized @325ms
onWebSocketError: java.nio.channels.ClosedChannelException
(在WssEmbedded服務器輸出上沒有任何更改)。
請幫助,如何讓WSS與嵌入式Jetty 9一起工作?
什麼具體的JVM您使用的?因爲JVM級別的SSL/TLS安全設置可能會妨礙您的發展。 –
我在64位Win 7上使用Oracle Java 1.8.0_66-b18,而我的生產服務器是64位CentOS 7 Linux,具有:java-1.8.0-openjdk-1.8.0.91-0.b14.el7_2.x86_64以及Oracle jdk1.8.0_91。剛剛在Mac OSX Yosemite上用Oracle jdk1.8.0_45.jdk嘗試過,並在[WssClient](https://github.com/afarber/jetty-newbie/)中獲得'onWebSocketError:org.eclipse.jetty.io.EofException'樹/主/ WssClient) –