我試圖通過具有基本身份驗證的代理通過HTTP客戶端4.4發送請求。 如果我輸入正確的憑證,則連接成功。Apache HttpClient 4.4代理基本身份驗證:多次驗證嘗試
但是,如果我輸入了錯誤的憑據,則即使使用正確的憑據,以下所有其他連接嘗試都將失敗。
似乎只要我們第一次提供了(錯誤的)憑證,新的(正確或錯誤的)憑證就不會被髮送。
你會看到有兩個電話:
- 第一個呼叫,錯誤的代理證書
- 第二個呼叫,正確的代理證書
代碼:
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 !!!!!!!!!!!!!!!!!
}
您可以在13:39:07:530的第一個日誌中看到它再次嘗試,並且這次是憑證(13:39:12:560 CEST [DEBUG]標頭 - http-outgoing-1代理授權:基本xXXxxXxXXXXX)。關於I/O錯誤,這是一個警告。 –