2014-01-13 71 views
7

我試圖讓灰熊使用SSL加密,並仍然與澤西工作正常。我已經瀏覽了整個互聯網,並且我發現在Grizzly和Jersey上有各種各樣的SSL嘗試。似乎有不同的做法取決於您使用的是哪個版本,以及您如何決定實施它。我還沒有能夠獲得任何示例來處理我的代碼。與灰熊和澤西島的SSL

以下是我啓動我的服務器:

static HttpServer startSecureServer() throws IOException{ 
     ResourceConfig rc=new PackagesResourceConfig("server.grizzlyresources"); 
     SSLContextConfigurator sslCon=new SSLContextConfigurator(); 

     sslCon.setKeyStoreFile(ConfigLoader.getKeystoreLocation()); // contains server keypair 
     sslCon.setKeyStorePass(ConfigLoader.getKeystorePassword()); 

     System.out.println("Starting server on port "+ConfigLoader.getHttpsServerPort()); 
     HttpServer secure=GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED, rc); 
     secure.stop(); 

     HashSet<NetworkListener> lists=new HashSet<NetworkListener>(secure.getListeners()); 
     for (NetworkListener listener : lists){ 
      listener.setSecure(true); 
      SSLEngineConfigurator ssle=new SSLEngineConfigurator(sslCon); 
      listener.setSSLEngineConfig(ssle); 
      secure.addListener(listener); 
      System.out.println(listener); 
     } 

     secure.start(); 
     return secure; 
} 

private static URI getBaseURISecured(){ 
    return UriBuilder.fromUri("https://0.0.0.0/").port(ConfigLoader.getHttpsServerPort()).build(); 
} 

private static final URI BASE_URI_SECURED = getBaseURISecured(); 

ConfigLoader負載從一個配置文件中的信息。當我運行這個代碼時,它啓動了服務器,它在server.grizzlyresources包中找到資源,它效果很好!除了一件事。服務器不安全。我可以telnet到它併發送一個純文本的HTTP請求爲我的資源之一,它會返回它。因此,該代碼適用於啓動服務器,但整個SSL部分只是被繞過。任何想法如何解決這個問題或爲什麼它可能會這樣做?

下面是輸出到控制檯當我運行它:

Starting server on port 9999 
Jan 13, 2014 9:51:08 AM com.sun.jersey.api.core.PackagesResourceConfig init 
INFO: Scanning for root resource and provider classes in the packages: 
    server.grizzlyresources 
Jan 13, 2014 9:51:08 AM com.sun.jersey.api.core.ScanningResourceConfig logClasses 
INFO: Root resource classes found: 
    class server.grizzlyresources.SessionResource 
    class server.grizzlyresources.LoginResource 
Jan 13, 2014 9:51:08 AM com.sun.jersey.api.core.ScanningResourceConfig init 
INFO: No provider classes found. 
Jan 13, 2014 9:51:08 AM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate 
INFO: Initiating Jersey application, version 'Jersey: 1.12 02/15/2012 04:51 PM' 
Jan 13, 2014 9:51:09 AM org.glassfish.grizzly.http.server.NetworkListener start 
INFO: Started listener bound to [0.0.0.0:9999] 
Jan 13, 2014 9:51:09 AM org.glassfish.grizzly.http.server.HttpServer start 
INFO: [HttpServer] Started. 
Jan 13, 2014 9:51:09 AM org.glassfish.grizzly.http.server.NetworkListener stop 
INFO: Stopped listener bound to [0.0.0.0:9999] 
NetworkListener{name='grizzly', host='0.0.0.0', port=9999, secure=true} 
Jan 13, 2014 9:51:09 AM org.glassfish.grizzly.http.server.NetworkListener start 
INFO: Started listener bound to [0.0.0.0:9999] 
Jan 13, 2014 9:51:09 AM org.glassfish.grizzly.http.server.HttpServer start 
INFO: [HttpServer] Started. 
我使用的是灰熊2.2.1和澤西1.12

非常感謝!

回答

3

IMO你可以使用不同的工廠方法來初始化安全灰熊的HttpServer:

HttpServer secure = GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED, 
         ContainerFactory.createContainer(HttpHandler.class, rc), 
         true, 
         new SSLEngineConfigurator(sslCon)); 

如果你初始化像這樣的服務器,你並不需要停止並再次重新配置。

希望這會有所幫助。

+0

感謝您的迴應!這不起作用,但它使我找到了一條我希望能夠找到解決方案的搜索路徑。服務器現在啓動安全,但當我嘗試使用'openssl s_client -connect localhost:9999'時,它在握手時死亡我想我可能只需要將所有內容遷移到澤西島的最新版本,該版本與澤西島有很大不同1.12,據我瞭解。如果我弄明白,我會回覆。 – user1389906

+1

您可以啓用SSL調試:「-Djavax.net.debug = all」,看看握手失敗的原因 – alexey

+1

非常感謝!調試信息表明它試圖驗證客戶端(我不希望它這樣做)。通過灰熊文檔,我發現在構建SSLEngineConfigurator時,我可以傳入布爾值,告訴它不要驗證客戶端。那樣做了! – user1389906

1

下面的代碼工作與灰熊2.3.7和我正在使用澤西1.18 - 這包括SSL客戶端驗證碼 - 如果你沒有密鑰存儲這個功能將被忽略。

/** 
* create a Server based on an url and possibly a ResourceConfig 
* 
* @param url 
* @param rc 
* @param secure 
*   - true if SSL should be used 
* @param contextPath 
* @return 
* @throws Exception 
*/ 
public HttpServer createHttpServer(String url, ResourceConfig rc, 
     boolean secure, String contextPath) throws Exception { 
    // HttpServer result = GrizzlyServerFactory.createHttpServer(url, rc); 
    // http://grepcode.com/file/repo1.maven.org/maven2/com.sun.jersey/jersey-grizzly2/1.6/com/sun/jersey/api/container/grizzly2/GrizzlyServerFactory.java#GrizzlyServerFactory.createHttpServer%28java.net.URI%2Ccom.sun.jersey.api.container.grizzly2.ResourceConfig%29 
    HttpServer result = new HttpServer(); 
    final NetworkListener listener = new NetworkListener("grizzly", 
      settings.getHost(), settings.getPort()); 
    result.addListener(listener); 
    // do we need SSL? 
    if (secure) { 
     listener.setSecure(secure); 
     SSLEngineConfigurator sslEngineConfigurator = createSSLConfig(true); 
     listener.setSSLEngineConfig(sslEngineConfigurator); 
    } 
    // Map the path to the processor. 
    final ServerConfiguration config = result.getServerConfiguration(); 
    final HttpHandler handler = ContainerFactory.createContainer(
      HttpHandler.class, rc); 
    config.addHttpHandler(handler, contextPath); 
    return result; 
} 

    /** 
* create SSL Configuration 
* 
* @param isServer 
*   true if this is for the server 
* @return 
* @throws Exception 
*/ 
private SSLEngineConfigurator createSSLConfig(boolean isServer) 
     throws Exception { 
    final SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator(); 
    // override system properties 
    final File cacerts = getStoreFile("server truststore", 
      "truststore_server.jks"); 
    if (cacerts != null) { 
     sslContextConfigurator.setTrustStoreFile(cacerts.getAbsolutePath()); 
     sslContextConfigurator.setTrustStorePass(TRUSTSTORE_PASSWORD); 
    } 

    // override system properties 
    final File keystore = getStoreFile("server keystore", "keystore_server.jks"); 
    if (keystore != null) { 
     sslContextConfigurator.setKeyStoreFile(keystore.getAbsolutePath()); 
     sslContextConfigurator.setKeyStorePass(TRUSTSTORE_PASSWORD); 
    } 

    // 
    boolean clientMode = false; 
    // force client Authentication ... 
    boolean needClientAuth = settings.isNeedClientAuth(); 
    boolean wantClientAuth = settings.isWantClientAuth(); 
    SSLEngineConfigurator result = new SSLEngineConfigurator(
      sslContextConfigurator.createSSLContext(), clientMode, needClientAuth, 
      wantClientAuth); 
    return result; 
} 
8

對不起,花了這麼長的時間來發布這裏。阿列克謝的回答讓我得到了工作解決方案,這很像沃爾夫岡法爾的代碼。以下是我最終得到的結果:

static HttpServer startSecureServer() throws IOException 
{ 
    System.out.println("Starting server on port " + ConfigLoader.getHttpsServerPort()); 
    ResourceConfig rc = new PackagesResourceConfig("com.kinpoint.server.grizzlyresources"); 

    SSLContextConfigurator sslCon = new SSLContextConfigurator(); 

    sslCon.setKeyStoreFile(ConfigLoader.getKeystoreLocation()); // contains server keypair 
    sslCon.setKeyStorePass(ConfigLoader.getKeystorePassword()); 

    HttpHandler hand = ContainerFactory.createContainer(HttpHandler.class, rc); 

    HttpServer secure = GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED, hand, true, 
      new SSLEngineConfigurator(sslCon, false, false, false)); 

    return secure; 
} 

SSLEngineConfigurator中的第二個參數告訴它不要使用客戶端模式。那就是搞砸了我。謝謝您的幫助。

+0

這是非常有用的。我注意到,當我使用僞造證書(密鑰庫位置/密碼)啓動我的服務器時,我沒有得到任何例外,但服務不可用。你的ConfigLoader是否做了一些驗證,或者你找到了另一種方法來發現錯誤? – Amber