2016-06-22 7 views
2

По этому вопросу я подготовил тестовый проект WssEmbedded, который прослушивает входящие соединения WebSocket по адресу localhost:8080 и localhost:8443.WebSocket через SSL во встроенном Jetty 9

В MyHandler классе я создаю 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 

screenshot

сервер запускается без проблем:

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-х лет для моего веб-доменов slova.de и www.slova.de (они указывают на разные IP-адреса !) и импортировать его на CentOS 7 Linux в хранилище с помощью Oracle jdk1.8.0_91-1.8.0_91-fcs.x86_64:

# 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 

Затем я начал программу WssEmbedded на www.slova.de:8443 (на моем сервере Linux это отличается IP адрес от slova.de, на котором Apache работает):

# 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?

+1

Какие конкретные JVM вы используете? Поскольку настройки безопасности SSL/TLS на уровне JVM могут мешать вам. –

+0

Я использую Oracle Java 1.8.0_66-b18 на 64-разрядном Win 7, а мой производственный сервер - это 64-разрядный CentOS 7 Linux с: java-1.8.0-openjdk-1.8.0.91-0.b14.el7_2.x86_64, а также Oracle jdk1.8.0_91. И просто попытался с помощью Oracle jdk1.8.0_45.jdk на Mac OSX Yosemite и получить 'onWebSocketError: org.eclipse.jetty.io.EofException' в [WssClient] (https://github.com/afarber/jetty-newbie/ дерево/ведущий/WssClient) –

ответ

1

После добавления -Dorg.eclipse.jetty.LEVEL=DEBUG -Djavax.net.debug=ssl дружелюбные люди на Jetty mailing list указали, что на стороне сервера были NPE, вызванные отсутствием HttpConnectionFactory.

Я пропустил копию этой части из примера embedded/LikeJettyXML.

Следующий код в wssembedded/MyHandler.java работает лучше:

public static void main(String[] args) throws Exception { 

    Server server = new Server(); 
    server.setHandler(new MyHandler()); 

    HttpConfiguration http_config = new HttpConfiguration(); 
    http_config.setSecureScheme("https"); 
    http_config.setSecurePort(8443); 

    HttpConfiguration https_config = new HttpConfiguration(http_config); 
    https_config.addCustomizer(new SecureRequestCustomizer()); 

    SslContextFactory sslContextFactory = new SslContextFactory(); 
    sslContextFactory.setKeyStorePath("keystore.jks"); 
    sslContextFactory.setKeyStorePassword("OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0"); 

    ServerConnector wsConnector = new ServerConnector(server); 
    wsConnector.setHost("localhost"); 
    wsConnector.setPort(8080); 
    server.addConnector(wsConnector); 

    ServerConnector wssConnector = new ServerConnector(server, 
     new SslConnectionFactory(sslContextFactory, 
      HttpVersion.HTTP_1_1.asString()), 
     new HttpConnectionFactory(https_config)); // THIS WAS MISSING 

    wssConnector.setHost("localhost"); 
    wssConnector.setPort(8443); 
    server.addConnector(wssConnector); 

    server.start(); 
    server.join(); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^