我正在使用Jersey Client 2.0庫(使用Apache HttpClient v4.2.5傳輸連接器)使用RESTful Web服務。我的應用程序必須支持通過代理服務器與基本,摘要或NTLM身份驗證的任何連接。我已經添加了對所有這些類型的代理身份驗證的支持,並且基本上一切工作都正常。重新使用授權標頭以防止澤西客戶端發生多個407代理身份驗證挑戰
這是我添加了基本和摘要代理身份驗證支持:
ClientConfig config = new ClientConfig();
config.property(ApacheClientProperties.PROXY_URI, "http://www.proxy.com:5678");
config.property(ApacheClientProperties.PROXY_USERNAME, "proxy_user");
config.property(ApacheClientProperties.PROXY_PASSWORD, "proxy_password");
ApacheConnector connector = new ApacheConnector(config);
config.connector(connector);
Client client = ClientBuilder.newClient(config);
另外,我連接到RESTful Web服務也需要基本身份驗證本身,這是我處理使用下列內容:
client.register(new HttpBasicAuthFilter("user", "password"));
但是,我的應用程序沒有像我想要的那樣運行:似乎每個單獨的HTTP請求都會導致來自代理服務器的407身份驗證質詢響應。這是有兩個原因的一個問題:
如果我做一個
POST
或PUT
請求(在已經成功地與先前的請求的代理服務器進行身份驗證)與由InputStream
提供的實體機構,它被視爲那麼當407的挑戰是收到我得到下面的異常「非重複」要求:org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
我可以解決此問題從
InputStream
實體主體的數據緩存到一個字符串或字節數組等等在407挑戰的情況下,請求是可重複的收到,但這是效率低下,並沒有解決問題2.- 不得不復制每個請求,首先觸發407挑戰,然後重複必要的額外的HTTP頭來代理驗證,是非常低效的。我的一些客戶操作涉及對RESTful Web服務的大量HTTP請求,因此這種額外的流量和延遲是不幸的。
我的期望是,一旦Jersey客戶端已成功地與代理服務器驗證的第一次,使用相同的Client
實例所做的所有後續請求將自動包含必要的Proxy-Authorization
頭,以防止任何進一步的407級的挑戰。這似乎是對HTTP 1.1按照this link的標準方法:
代理服務器向客戶機發送一個Proxy-Authenticate頭,含有一個挑戰,在407(代理身份驗證必需的)的反應。然後客戶端重複初始請求,但添加了包含適合挑戰的憑證的代理授權標頭。在成功進行代理驗證之後,客戶端通常會向每個後續請求的代理髮送相同的代理授權頭,而不是等待再次提出質詢。
所以我的問題是,我需要將哪些配置設置應用於Jersey客戶端或底層Apache HttpClient傳輸層以啓用此行爲?我見過各種其他帖子,建議手動添加Proxy-Authorization
標題,但我寧願儘可能避免此解決方法。我也理想地尋找一種解決方案,可以與我使用的所有三種類型的代理身份驗證(基本,摘要和NTLM)一起使用。
如果無法防止所有這些額外的407挑戰,我還希望在以可重複的方式從本地文件發佈或提取數據以防止407代理身份驗證挑戰後的問題時提供最佳方法。