2015-10-07 35 views
2

我試圖通過具有基本身份驗證的代理通過HTTP客戶端4.4發送請求。 如果我輸入正確的憑證,則連接成功。Apache HttpClient 4.4代理基本身份驗證:多次驗證嘗試

但是,如果我輸入了錯誤的憑據,則即使使用正確的憑據,以下所有其他連接嘗試都將失敗。

似乎只要我們第一次提供了(錯誤的)憑證,新的(正確或錯誤的)憑證就不會被髮送。

你會看到有兩個電話:

  1. 第一個呼叫,錯誤的代理證書
  2. 第二個呼叫,正確的代理證書

代碼:

package test; 

import org.apache.commons.codec.binary.Base64; 
import org.apache.http.HttpHost; 
import org.apache.http.HttpResponse; 
import org.apache.http.auth.AuthScope; 
import org.apache.http.auth.UsernamePasswordCredentials; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpUriRequest; 
import org.apache.http.client.protocol.HttpClientContext; 
import org.apache.http.impl.client.HttpClientBuilder; 
import org.apache.http.impl.client.HttpClients; 

public class Main { 

    private HttpClient client; 
    private HttpClientContext context = HttpClientContext.create(); 

    public static void main(String[] args) throws Exception { 
     System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); 
     System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); 
     System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "DEBUG"); 
     System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "ERROR"); 

     Main main = new Main(); 
     main.createHttpClient(); 
     main.send(true, "test", "wrong"); // 1st call, wrong credentials, if this call is removed, it works ! 
     main.send(true, "test", "correct"); // 2nd call, correct credentials 
    } 

    public void send(String username, String password) throws Exception { 
     proxyAuthenticate(username, password); 

     HttpUriRequest request = new HttpGet("https://the-backend.xyz"); 
     HttpResponse httpResponse = client.execute(request, context); 
     int statusCode = httpResponse.getStatusLine().getStatusCode(); 
     System.out.println("######################### " + statusCode); 
    } 

    public void createHttpClient() throws Exception { 
     HttpClientBuilder httpClientBuilder = HttpClients.custom(); 
     httpClientBuilder.setProxy(new HttpHost("proxy.the-proxy.xyz", 1234)); 
     client = httpClientBuilder.build(); 
    } 

    private void proxyAuthenticate(String username, String password) { 
     UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password); 
     AuthScope scope = new AuthScope("proxy.the-proxy.xyz", 1234); 

     CredentialsProvider provider = new BasicCredentialsProvider(); 
     provider.setCredentials(scope, credentials); 

     context.setCredentialsProvider(provider); 
    } 

} 

的記錄第一次嘗試(連接錯誤的代理信譽:兩個http請求一個沒有信用,一個用vim的信任狀,既返回407,看起來邏輯):

2015年10月7日13:39:02:502 CEST [WARN] BasicAuthCache - 意外的I/O錯誤 在序列AUTH方案java.io.NotSerializableException :test.Main在 java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) 在 java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 在 java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream中。 java:1508) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 在 java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 在 org.apache.http.impl.client.BasicAuthCache.put(BasicAuthCache的.java:107) 在test.Main.proxyAuthenticate(Main.java:109)在 test.Main.send(Main.java:56)在test.Main2.main(Main2.java:30)

2015/10/07 13:39:02:502 CEST [DEBUG] RequestAddCookies - CookieSpec selected:default 2015/10/07 13:39:02:502 CEST [調試] PoolingHttpClientConnectionManager - 連接請求:[路由: { tls} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持活着:0;分配的路由:3箇中的0個;總分配:2015年10月7日13 0 3] :39:02:502 CEST [DEBUG] PoolingHttpClientConnectionManager - 連接租用:[ID:1] [路線: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持活:0;分配的路由:3箇中的1個;總分配:2015年10月7日13 1 3] :39:02:502 CEST [DEBUG] MainClientExec - 打開 連接 {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443 2015年10月7日13時39分02秒: 502 CEST [DEBUG] DefaultHttpClientConnectionOperator - 連接到 proxy.the-proxy.xyz/123.45.67.890:1234 2015年10月7日13:39:07:530 CEST [DEBUG] DefaultHttpClientConnectionOperator - 連接建立 321.54.76.098: 58216 < - > 123.45.67。890:1234 2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 >> CONNECT the-backend.xyz:443 HTTP/1.1 2015/10/07 13:39:07 :530 CEST [DEBUG] headers - http-outgoing-1 >>主機: the-backend.xyz 2015/10/07 13:39:07:530 CEST [調試] 頭文件 - http-outgoing-1 >> User-Agent:Apache-HttpClient/4.4.1 (Java/1.7.0_51)2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 < < HTTP/1.1 407 Proxy需要身份驗證 2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 < < Proxy-Authenticate:BASIC realm =「InternetAccess」2015/10/07 13:39:07 :530 CEST [DEBUG]頭文件 - http-outgoing-1 < < Cache-Control: no-cache 2015/10/07 13:39:07:530 CEST [DEBUG]頭文件 - http-outgoing-1 < < Pragma:no-cache 2015/10/07 13:39: 07:530 CEST [DEBUG] headers - http-outgoing-1 < < Content-Type:text/html; charset = utf-8 2015/10/07 13:39:07:530 CEST [DEBUG]頭文件 - http-outgoing-1 < <代理連接:關閉2015/10/07 13:39:07:530 CEST [DEBUG] headers -http-outgoing-1 < < Connection:close 2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 < < Content-Length: 2916 2015/10/07 13:39:07:530 CEST [DEBUG] HttpAuthenticator - 需要身份驗證2015/10/07 13:39:07:530 CEST [調試] HttpAuthenticator - proxy.the-proxy.xyz:1234請求身份驗證 2015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy - 訂單中的驗證方案[談判, Kerberos,NTLM,摘要,基本] 2015/10/07 13:39:07:530 CEST [調試] ProxyAuthenticationStrategy - 協商身份驗證的挑戰 方案不可用2015/10/07 13:39 :07:530 CEST [調試] ProxyAuthenticationStrategy - 對Kerberos身份驗證的挑戰 方案不可用2015/10/07 13:39:07:530 CEST [調試] ProxyAuthenticationStrategy - NTLM身份驗證方案的挑戰 不可用2015/10/07 13:39:07:530 CEST [調試] ProxyAuthenticationStrategy - 對摘要式身份驗證的挑戰 計劃不可用2015/10/07 13:39:07:530 CEST [調試] HttpAuthenticator - 選擇的身份驗證選項:[BASIC [complete = true]] 2015/10/07 13:39:07:530 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:關閉連接 2015/10/07 13:39:07:530 CEST [DEBUG ] DefaultHttpClientConnectionOperator - 連接到 proxy.the-proxy.xyz/123.45.67.890:1234 2015年10月7日13:39:12:560 CEST [DEBUG] DefaultHttpClientConnectionOperator - 連接建立 321.54.76.098:58217 < - > 123.45.67.890:1234 2015/10/07 13:39:12:560 CEST [DEBUG] HttpAuthenticator - 生成對身份驗證的響應 使用基本方案的挑戰2015/10/07 13:39:12:560 CEST [調試] 頭文件 - http-outgoing-1 >> CONNECT the-backend.xyz:443 HTTP/1.1 2015/10/07 13:39:12:560 C EST [DEBUG]標頭 - http-outgoing-1 >>主機: the-backend.xyz 2015/10/07 13:39:12:560 CEST [調試] 標頭 - http-outgoing-1 >>用戶代理:Apache-HttpClient/4.4.1 (Java/1.7。0_51)2015/10/07 13:39:12:560 CEST [DEBUG] headers - http-outgoing-1 >> Proxy-Authorization:Basic xXXxxXxXXXXX 2015/10/07 13:39:12:561 CEST [DEBUG ]報頭 - HTTP出射-1 < < HTTP/1.1 407 代理身份驗證2015年10月7日13:39:12:561 CEST [DEBUG] 頭 - HTTP出射-1 < <代理驗證:BASIC realm =「InternetAccess」2015/10/07 13:39:12:561 CEST [DEBUG] headers - http-outgoing-1 < < Cache-Control:no-cache 2015/10/07 13:39:12:561 CEST [DEBUG] headers - http-outgoing-1 < < Pragma:no-cache 2015/10/07 13:39:12:561 CEST [DEBUG] he aders - http-outgoing-1 < < Content-Type: text/html; charset = utf-8 2015/10/07 13:39:12:561 CEST [DEBUG]頭文件 - http-outgoing-1 < <代理連接:關閉2015/10/07 13:39:12:561 CEST [ DEBUG]頭文件 - http-outgoing-1 < < <連接:close 2015/10/07 13:39:12:561 CEST [DEBUG] headers - http-outgoing-1 < < Content-Length: 2966 2015/10/07 13:39:12:561 CEST [DEBUG] HttpAuthenticator - 需要身份驗證2015/10/07 13:39:12:561 CEST [調試] HttpAuthenticator - proxy.the-proxy.xyz:1234請求身份驗證 2015/10/07 13:39:12:561 CEST [DEBUG] HttpAuthenticator - 授權 處理的挑戰2015/10/07 13:39:12:561 CEST [調試] HttpAu驗證失敗2015/10/07 13:39:12:561 CEST [DEBUG] ProxyAuthenticationStrategy - 清除緩存的認證方案 http://proxy.the-proxy.xyz:1234 2015/10/07 13:39:12:561 CEST [調試] DefaultManagedHttpClientConnection - http -outgoing-1:關閉連接 2015/10/07 13:39:12:561 CEST [DEBUG] MainClientExec - CONNECT拒絕 代理服務器:HTTP/1.1 407代理服務器驗證必需2015/10/07 13:39:12 :561 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:關閉連接2015/10/07 13:39:12:561 CEST [調試] MainClientExec - 連接丟棄2015/10/07 13:39:12:561 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:關閉 連接2015年10月7日13:39:12:561 CEST [DEBUG] PoolingHttpClientConnectionManager - 釋放連接:[ID: 1] [路線: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持存活:0;分配的路由:3箇中的0個;總分配:0的3]

################### 407

爲第二嘗試的日誌(連接與正確的代理名氣:只有一個HTTP請求,爲什麼沒有與正確的creds ???)的第二請求:

2015年10月7日13:39:17:585 CEST [WARN] BasicAuthCache - 意外的I/O 而錯誤序列化認證方案java.io.NotSerializableException:test.Main at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) at java.io.ObjectOutputStream.d efaultWriteFields(ObjectOutputStream.java:1547) 在 java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 在 java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 在 java.io.ObjectOutputStream中.writeObject0(ObjectOutputStream中。的java:1177) 在 java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 在 org.apache.http.impl.client.BasicAuthCache.put(BasicAuthCache.java:107) 在test.Main。代理驗證(Main.java:109) test.Main.send(Main.java:56)at test.Main2.main(Main2.java:32)

2015/10/07 13:39:17: 585 CEST [調試] RequestAddCookies - CookieSpec 選自:默認2015年10月7日13:39:17:585 CEST [DEBUG] PoolingHttpClientConnectionManager - 連接請求:[路線: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持存活: 0;分配的路由:3箇中的0個;總分配:2015年10月7日13 0 3] :39:17:585 CEST [DEBUG] PoolingHttpClientConnectionManager - 連接租用:[ID:2] [路線: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持活:0;分配的路由:3箇中的1個;總分配:2015年10月7日13 1 3] :39:17:585 CEST [DEBUG] MainClientExec - 打開 連接 {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443 2015年10月7日13時39分十七秒: 585 CEST [DEBUG] DefaultHttpClientConnectionOperator - 連接到 proxy.the-proxy.xyz/123.45.67.890:1234 2015年10月7日13:39:17:585 CEST [DEBUG] DefaultHttpClientConnectionOperator - 連接建立 321.54.76.098: 58218 < - > 123.45.67.890:1234 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 >> CONNECT the-backend.xyz:443 HTTP/1.1 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 >>主機: the-backend.xyz 2015/10/07 13:39:17:586 CEST [調試] 頭部 - http-outgoing-2 >>用戶代理:Apache-HttpClient/4.4.1 (Java/1.7.0_51)2015/10/07 13:39:17:586 CEST [DEBUG]頭文件 - http-outgoing-2 < < HTTP/1.1 407需要代理驗證 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing -2 < < 代理驗證:BASIC境界= 「及網絡連接。」 2015年10月7日13 :39:17:586 CEST [DEBUG]報頭 - HTTP出射-2 < <緩存控制: 無緩存2015/10/07 13:39:17:586 CEST [DEBUG]頭文件 - http-outgoing-2 < < Pragma:no-cache 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 < < Content-Type:text/html; charset = utf-8 2015/10/07 13:39:17:586 CEST [DEBUG]頭文件 - http-outgoing-2 < <代理連接:關閉2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 < <連接:close 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 < < Content-Length: 2916 2015/10/07 13:39:17:586 CEST [DEBUG] HttpAuthenticator - 需要身份驗證2015/10/07 13:39:17:586 CEST [調試] HttpAuthenticator - proxy.the-proxy.xyz:1234請求身份驗證 2015/10/07 13:39:17:586 CEST [調試] DefaultManagedHttpClientConnection - http-outgoing-2:關閉連接ction 2015/10/07 13:39:17:586 CEST [DEBUG] MainClientExec - CONNECT拒絕 通過代理:HTTP/1。1 407需要代理驗證2015/10/07 13:39:17:586 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-2:關閉連接2015/10/07 13:39:17:586 CEST [調試] MainClientExec - 連接丟棄2015/10/07 13:39:17:586 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-2:關閉 連接2015/10/07 13:39:17:586 CEST [調試] PoolingHttpClientConnectionManager - 已發佈的連接:[id: 2] [route: {tls} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total keep alive:0;分配的路由:3箇中的0個;總分配:0 3]

################### 407

任何想法,爲什麼在第2次嘗試,它試圖未經身份驗證(正常),服務器會回覆基本身份驗證是必需的,然後不是使用正確的憑據進行嘗試,而是關閉連接。

謝謝!

UPDATE:

如果我改變的HttpClient(4.4),以DefaultHttpClient(4.3)和適應這兩種方法,它的工作原理。 請注意,getCredentialsProvider從4.3的客戶端和4.4的上下文中調用!

第一次我收到407狀態碼,但第二次收到200,這是我所期望的。

public void createHttpClient() throws Exception { 
    client = new DefaultHttpClient(); 
    HttpHost proxy = new HttpHost("proxy.eurocontrol.be", 9513); 
    ConnRouteParams.setDefaultProxy(client.getParams(), proxy); 
} 

private void proxyAuthenticate(String username, String password) { 
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password); 
    AuthScope scope = new AuthScope("proxy.eurocontrol.be", 9513); 
    client.getCredentialsProvider().setCredentials(scope, credentials); 
    // Called from client !!!!!!!!!!!!!!!!! 
} 

回答

0

代碼的第一行清楚地表明這兩個請求都已完成。

First at - 2015/10/07 13:39:02:502 

Second at - 2015/10/07 13:39:17:585 

什麼要打印的是服務器響應的狀態代碼,請參閱thisHttp Status 407

即使你的日誌說清楚

Unexpected I/O error while serializing auth scheme java.io.NotSerializableException 

可以有一個例外,因爲串行化也。

+0

您可以在13:39:07:530的第一個日誌中看到它再次嘗試,並且這次是憑證(13:39:12:560 CEST [DEBUG]標頭 - http-outgoing-1代理授權:基本xXXxxXxXXXXX)。關於I/O錯誤,這是一個警告。 –