2016-10-17 237 views
1

我使用CXF 3.1.5,我試圖使它與代理一起使用。如果沒有用戶名和密碼的代理,那麼它的工作原理;如果有代理的用戶名和密碼,那麼它不起作用。這裏是我的代碼:
爲CXF設置ProxyAuthorizationPolicy httpConduit不起作用

//to create my own http conduit 
bus.setExtension(new TLSAndProxySupportedHTTPConduitFactory(settings, HTTPConduitFactory.class); 
//to get wsdl definition 
Definition definition = bus.getExtension(WSDLManager.class).getDefinition(uri); 

TLSAndProxySupportedHTTPConduitFactory實現HTTPConduitFactory,並將創建一個TLSAndProxySupportedHTTPConduit延伸URLConnectionHTTPConduit,在TLSAndProxySupportedHTTPConduit,這裏是代理設置相關的代碼:

  //HTTPClientPolicy settings works 
     HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); 
     httpClientPolicy.setProxyServer(proxy.getHostName()); 
     httpClientPolicy.setProxyServerPort(proxy.getPort()); 

     this.setClient(httpClientPolicy); 

     if (proxy.getUserName() != null) { 
      //ProxyAuthorizationPolicy settings doesn't work 
      this.getProxyAuthorization().setUserName(proxy.getUserName()); 
      this.getProxyAuthorization().setPassword(proxy.getPassword()); 

     } 

請記住,如果代理沒有用戶名和密碼,一切正常,如果加載WSDL定義的目標URL開始於https(https需要我),代理不起作用。如果它是以http開頭的,那麼帶有用戶名和密碼的代理運行良好。

回答

1

找到一個解決方案:
原因是

Sun Microsystems的Java安全套接字擴展(JSSE)庫可以讓用戶通過代理隧道從防火牆後面訪問一個安全的Web服務器。爲此,JSSE應用程序需要設置https.ProxyHost和https.ProxyPort系統屬性。 JSSE中的隧道代碼在代理響應中檢查「HTTP 1.0」。如果您的代理與許多代理一樣返回「HTTP 1.1」,您將得到一個IOException。在這種情況下,您需要實施您自己的HTTPS隧道協議。

全球化志願服務青年:http://www.javaworld.com/article/2077475/core-java/java-tip-111--implement-https-tunneling-with-jsse.html
https://community.oracle.com/thread/1534538


然後,你可以覆蓋URLConnectionHTTPConduit的方法setupConnection。

@Override 
protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException { 
    super.setupConnection(message, address, csPolicy); 
    HttpURLConnection connection = (HttpURLConnection) message.get(KEY_HTTP_CONNECTION); 
    decorateHttpsURLConnection((HttpsURLConnection) connection);\ 
    message.put(KEY_HTTP_CONNECTION, connection); 
} 
在該方法中decorateHttpsURLConnection

httpsConnection.setSSLSocketFactory(new SSLTunnelSocketFactory(getProxy(), sslContext.getSocketFactory()));