2016-07-25 56 views
0

今天我試圖配置使用Apache的org.apache.httpcomponents.httpclient庫的HttpComponentsMessageSender。在使用標準的Java類之前(我認爲java.net.HttpUrlMessageSender或者其他的東西)。HttpComponentMessageSender NTLM

我的HTTP方法需要使用NTLM進行身份驗證,並且該軟件在Linux下運行,因此我不能使用默認的Windows機制來進行身份驗證,而是必須在Java應用程序中配置身份驗證。

本來我只是使用java.net.Authenticator的一個自定義實現,我用它來設置用戶名和密碼 爲NTLM訪問。但是當我切換到HttpComponentsMessageSender這種方法不再工作。當我試圖用HttpComponentsMessageSender設置自定義HttpClient配置時,我遇到了各種我認爲會在此處記錄的問題。

我打算髮表我自己的回答,但如果有人有更好的解決方案,請隨時添加您的解決方案。

回答

0

我解決了這個問題,我用HttpClientBuilder構建了一個定製的構建HttpClient對象。然而加入這引起了以下異常出現:

org.apache.http.ProtocolException:Content-Length頭已經存在

  1. 我在this answer發現解決的辦法是增加一個HttpRequestInterceptor
  2. 使用HttpComponentsMessageSender上的setConnectionTimeout不再適用於我自定義的HttpClient對象。相反,我必須在HttpClientBuilder中注入RequestConfig對象。
  3. NTCredentials對象要求域名作爲參數。之前當我使用Authenticator接口java.net時,只需提供用戶名和密碼即可。

這是我目前使用的代碼:

HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender(); 
AuthScope authscope; 
NTCredentials credentials; 
CredentialsProvider credentialsProvider; 
Registry<AuthSchemeProvider> registry; 
RequestConfig requestConfig; 

authscope = new AuthScope (HOST_IP, HOST_PORT); 

credentials = new NTCredentials ("user", "pass", null, "domain"); 

credentialsProvider = new BasicCredentialsProvider(); 

credentialsProvider.setCredentials (authscope, credentials); 

registry = RegistryBuilder.<AuthSchemeProvider>create() 
     .register(AuthSchemes.NTLM, new NTLMSchemeFactory()) 
     .build(); 

HttpRequestInterceptor interceptor 
     = (request, context) -> request.removeHeaders(HTTP.CONTENT_LEN); 

requestConfig = RequestConfig.custom() 
          .setConnectTimeout (3000) 
          .build(); 

HttpClient httpClient 
    = HttpClientBuilder.create() 
         .setDefaultRequestConfig (requestConfig) 
         .setDefaultAuthSchemeRegistry (registry) 
         .setDefaultCredentialsProvider (credentialsProvider) 
         .addInterceptorFirst (interceptor) 
         .build(); 

messageSender.setHttpClient (httpClient);