2

我正在使用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身份驗證質詢響應。這是有兩個原因的一個問題:

  1. 如果我做一個POSTPUT請求(在已經成功地與先前的請求的代理服務器進行身份驗證)與由InputStream提供的實體機構,它被視爲那麼當407的挑戰是收到我得到下面的異常「非重複」要求:

    org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity. 
    

    我可以解決此問題從InputStream實體主體的數據緩存到一個字符串或字節數組等等在407挑戰的情況下,請求是可重複的收到,但這是效率低下,並沒有解決問題2.

  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代理身份驗證挑戰後的問題時提供最佳方法。

回答

2

最後,我解決了問題1,將我的項目升級到Jersey Client v2.6並配置客戶端以自動緩存我的所有POST/PUT請求,以便它們「可重複」以響應任何407來的挑戰從代理服務器返回。

請求緩衝可以在Jersey客戶端V2.5 +通過設置ClientConfig對象,它從「分塊」(缺省值)爲「緩衝」改變請求實體處理模式在以下屬性來啓用:

config.property(ClientProperties.REQUEST_ENTITY_PROCESSING, 
       RequestEntityProcessing.BUFFERED); 

現在,我需要支持所有三種類型的代理認證:Basic,Digest和NTLM。我只在用戶配置代理服務器時啓用這個「緩衝」模式,因爲我認爲除非絕對必要,否則最好堅持默認的「分塊」模式。我擔心緩衝內存中大量PUT/POST請求的開銷,以及在不分塊數據時可能會損失效率。

因此,現在我的客戶端應用程序可以正常工作,但我仍然非常有興趣瞭解任何可能的解決方案問題2,因爲最好只觸發每個Client實例的單個初始407代理身份驗證挑戰。由於Digest和NTLM身份驗證的固有附加複雜性,我懷疑這個問題的任何潛在解決方案都只能用於基本身份驗證。

相關問題