2016-01-12 62 views
2

我試圖建立一個安全的WebSocket服務器碼頭這樣的:設置了碼頭和JavaScript客戶端提供安全的WebSocket服務器

import java.util.ArrayList; 
import java.util.List; 

import org.eclipse.jetty.http.HttpVersion; 
import org.eclipse.jetty.server.Handler; 
import org.eclipse.jetty.server.HttpConfiguration; 
import org.eclipse.jetty.server.HttpConnectionFactory; 
import org.eclipse.jetty.server.Server; 
import org.eclipse.jetty.server.ServerConnector; 
import org.eclipse.jetty.server.SslConnectionFactory; 
import org.eclipse.jetty.server.handler.ContextHandler; 
import org.eclipse.jetty.server.handler.HandlerCollection; 
import org.eclipse.jetty.util.ssl.SslContextFactory; 
import org.eclipse.jetty.websocket.server.WebSocketHandler; 
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; 


public class WebSocketServer 
{ 
    private Server server; 
    private String host="localhost"; 
    private int port=8080; 
    private String keyStorePath = "C:\\keystore"; 
    private String keyStorePassword="password"; 
    private String keyManagerPassword="password"; 
    private List<Handler> webSocketHandlerList = new ArrayList(); 
    MessageHandler messagehandler; 

    public WebSocketServer() 
    { 
     System.out.println("WebSocketServer"); 

     server = new Server(); 

     // connector configuration 
     SslContextFactory sslContextFactory = new SslContextFactory(); 
     sslContextFactory.setKeyStorePath(keyStorePath); 
     sslContextFactory.setKeyStorePassword(keyStorePassword); 
     sslContextFactory.setKeyManagerPassword(keyManagerPassword); 
     SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()); 
     HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory(new HttpConfiguration()); 
     ServerConnector sslConnector = new ServerConnector(server, sslConnectionFactory, httpConnectionFactory); 
     sslConnector.setHost(host); 
     sslConnector.setPort(port); 
     server.addConnector(sslConnector); 

     // handler configuration 
     HandlerCollection handlerCollection = new HandlerCollection(); 
     handlerCollection.setHandlers(webSocketHandlerList.toArray(new Handler[0])); 
     server.setHandler(handlerCollection); 

     WebSocketHandler wsHandler = new WebSocketHandler() { 
      @Override 
      public void configure(WebSocketServletFactory webSocketServletFactory) { 
       webSocketServletFactory.register(MyWebSocketHandler.class); 
      } 
     }; 
     ContextHandler wsContextHandler = new ContextHandler(); 
     wsContextHandler.setHandler(wsHandler); 
     wsContextHandler.setContextPath("/"); // this context path doesn't work ftm 
     webSocketHandlerList.add(wsHandler); 

     messagehandler = new MessageHandler(); 
     new Thread(messagehandler).start(); 

     try { 
      server.start(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

密鑰庫文件使用下面的命令創建發現here在JDK/bin文件夾:

keytool.exe -keystore keystore -alias jetty -genkey -keyalg RSA 

之後,我將文件移動到C目錄以便於路徑使用。

有了這個配置我的服務器似乎開始沒有任何問題。所以,我想我的網站連接到它是這樣的:

ws = new WebSocket("wss://localhost:8080/"); 

這並不在所有的工作。像寫入here,我想我必須配置SSL證書。此外,爲了創建服務器,我使用了這個tutorial,對於java客戶端,他們實現了truststore。我是否必須爲JavaScript做類似的事情?

回答

7

答案可能有點晚,但是我經過多次嘗試後纔開始工作。


一些一般考慮第一:

  • 作爲一般規則遵循(有效期爲node.js的,太),您必須首先做出WSS工作HTTPS工作。 WebSocket通過HTTP工作,所以如果你的服務器已經正確配置了HTTPS(或HTTP),那麼向它添加WebSocket將使WSS(或WS)工作。實際上HTTPS/WSS和HTTP/WS都可以同時工作

  • 證書是非常重要的,因爲並非所有類型的證書都可以在Jetty中工作(node.js也是如此)。所以你必須生成Jetty將接受的證書。

  • 使HTTPS工作同樣重要的是自簽名證書,因爲你可能通過HTTPS必須先訪問服務器,並添加異常之前WSS可以工作(這可能取決於瀏覽器。)

  • 需要考慮的另一件事是上下文路徑也需要被正確設置。我通過爲HTTP和WS分開路徑來實現它,例如用於HTTP(S)的/hello和用於WS(S)的/ws。這可能是可能的上是相同的上下文路徑做到這一點,但我沒有調查這還


下面是我遵循的步驟。 我在GitHub上放了一個working example

1)通過使用從here

命令上述連桿具有關於如何生成正確的自簽名證書的示例生成正確的自簽名的證書。 (如果你有CA簽名的證書,我認爲程序有些不同。)

我在這裏粘貼命令以方便訪問。請注意,每次詢問時都要始終輸入相同的密碼(包括最後一個步驟中的一個,當您鍵入的密碼將以明文顯示在屏幕上時)。

openssl genrsa -aes256 -out jetty.key 
openssl req -new -x509 -key jetty.key -out jetty.crt 
keytool -keystore keystore -import -alias jetty -file jetty.crt -trustcacerts 
openssl req -new -key jetty.key -out jetty.csr 
openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12 
keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore 

2)在Jetty中有正確的HTTPS代碼。

網上有一些資源顯示瞭如何使用Jetty執行HTTPS,但對於我來說只有一個工作,並且它是here

3)有正確的代碼來處理上下文。

這一個很難 - 從Jetty文檔頁面的示例代碼不適合我。 工作原理是this。本教程還告訴我,如果我嘗試對HTTP和WS使用相同的路徑,可能會發生衝突。

4)最後,對WebSocket的

我找到了正確的WebSocket代碼here正確的代碼。有我們需要的是native-jetty-websocket-example

+0

感謝您的工作!這個問題還在我的列表上。下個月,當我回來工作時,我會嘗試你的答案。 – Steckdoserich