2012-11-08 5 views
2

HttpClient 4.2.2 및 사용자 이름/암호가있는 프록시에 문제가 있습니다. 이 방식으로 작동 HttpClient를 :HttpClient 4.2.2 및 사용자 이름/암호가있는 프록시

  1. 프록시 물건이없는
  2. 보내기 요청이
  3. 407 오류 프록시와
  4. 보내기 요청과 오징어에서 응답을 받기 (그러나 나는 각 요청에 대한 프록시 매개 변수를 설정)
  5. 목록 항목 물건

매우 이상한 행동입니다. 각 요청에 프록시에 대한 정보를 추가 할 수 있습니까? 나는 각 요청에 하드 코딩 된 "Proxy-Authorization"헤더를 추가하려고 시도했으며 HttpClient가 동일한 작업을 수행 할 수없는 이유는 무엇입니까?

자바 하드 헤더와 코드

DefaultHttpClient httpClient = new DefaultHttpClient(); 
httpClient.getParams().setParameter(PROTOCOL_VERSION, HTTP_1_1); 
... 
String proxyServer = getProxyServer(); 
int proxyPort = getProxyPort(); 
List<String> authpref = new ArrayList<String>(); 
authpref.add(AuthPolicy.BASIC); 
httpClient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref); 
String proxyUser = getProxyUser(); 
String proxyPassword = getProxyPassword(); 
CredentialsProvider credsProvider = httpClient.getCredentialsProvider(); 
credsProvider.setCredentials(new AuthScope(proxyServer, proxyPort), new UsernamePasswordCredentials(proxyUser, proxyPassword)); 
httpClient.setCredentialsProvider(credsProvider); 
HttpHost proxy = new HttpHost(proxyServer, proxyPort, (proxyServer.indexOf("https") != 0) ? "http" : "https"); 
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); 
... 
HttpPut put = new HttpPut(url); 

/*** hardcoded header ***/ 
//put.addHeader("Proxy-Authorization", "Basic eHRlbmR4LmRuZXByOnF3ZXJ0eQ=="); 
/*** hardcoded header ***/ 

put.setEntity(entity); 
httpClient.execute(put); 
httpClient.getConnectionManager().shutdown(); 


[DefaultClientConnection] Sending request: PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg HTTP/1.1 
[headers] >> PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg HTTP/1.1 
[headers] >> Authorization: Basic eGRldjo0YTFmNmMwOTgyYWRkMWQ0NDg1YjRhMGE4YWMxY2JjMWNiMTA0ODc1 
[headers] >> Content-Length: 2 
[headers] >> Host: 172.26.27.22:8080 
[headers] >> Proxy-Connection: Keep-Alive 
[headers] >> User-Agent: Apache-HttpClient/4.2.2 (java 1.5) 
[DefaultClientConnection] Receiving response: HTTP/1.0 407 Proxy Authentication Required 
[headers] << HTTP/1.0 407 Proxy Authentication Required 
[headers] << Server: squid/2.7.STABLE8 
[headers] << Date: Thu, 08 Nov 2012 10:09:49 GMT 
[headers] << Content-Type: text/html 
[headers] << Content-Length: 1431 
[headers] << X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0 
[headers] << Proxy-Authenticate: Basic realm="Please, enter username and password" 
[headers] << X-Cache: MISS from 172.26.27.94 
[headers] << X-Cache-Lookup: NONE from 172.26.27.94:3128 
[headers] << Via: 1.0 172.26.27.94:3128 (squid/2.7.STABLE8) 
[headers] << Connection: close 
[DefaultHttpClient] Authentication required 
[DefaultHttpClient] 172.26.27.94:3128 requested authentication 
[ProxyAuthenticationStrategy] Authentication schemes in the order of preference: [Basic] 
[DefaultHttpClient] Selected authentication options: [BASIC] 
[DefaultClientConnection] Connection 0.0.0.0:63344<->172.26.27.94:3128 closed 
[DefaultClientConnectionOperator] Connecting to 172.26.27.94:3128 
[RequestAddCookies] CookieSpec selected: best-match 
[RequestAuthCache] Re-using cached 'basic' auth scheme for http://172.26.27.22:8080 
[RequestAuthCache] No credentials for preemptive authentication 
[RequestProxyAuthentication] Proxy auth state: CHALLENGED 
[RequestProxyAuthentication] Generating response to an authentication challenge using basic scheme 
[DefaultHttpClient] Attempt 2 to execute request 
[DefaultClientConnection] Sending request: PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg HTTP/1.1 
[headers] >> PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg HTTP/1.1 
[headers] >> Authorization: Basic eGRldjo0YTFmNmMwOTgyYWRkMWQ0NDg1YjRhMGE4YWMxY2JjMWNiMTA0ODc1 
[headers] >> Content-Length: 2 
[headers] >> Host: 172.26.27.22:8080 
[headers] >> Proxy-Connection: Keep-Alive 
[headers] >> User-Agent: Apache-HttpClient/4.2.2 (java 1.5) 
[headers] >> Proxy-Authorization: Basic eHRlbmR4LmRuZXByOnF3ZXJ0eQ== 
[DefaultClientConnection] Receiving response: HTTP/1.0 201 Created 
[headers] << HTTP/1.0 201 Created 
[headers] << Content-Length: 0 
[headers] << Date: Thu, 08 Nov 2012 10:09:49 GMT 
[headers] << X-Cache: MISS from 172.26.27.94 
[headers] << X-Cache-Lookup: MISS from 172.26.27.94:3128 
[headers] << Via: 1.1 172.26.27.94:3128 (squid/2.7.STABLE8) 
[headers] << Connection: keep-alive 
[headers] << Proxy-Connection: keep-alive 

오징어 로그

1352370666.778  0 172.26.27.94 TCP_DENIED/407 1870 PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg - NONE/- text/html 
1352370671.429  8 172.26.27.94 TCP_MISS/201 282 PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg proxyuser DIRECT/172.26.27.22 - 
1352370671.474  0 172.26.27.94 TCP_DENIED/407 1882 PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image2.jpg - NONE/- text/html 
1352370671.486  7 172.26.27.94 TCP_MISS/201 282 PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image2.jpg proxyuser DIRECT/172.26.27.22 - 

에는 407 자바 로그에 오류, 오징어 로그가 없습니다

오징어 로그

1352370542.016  8 172.26.27.94 TCP_MISS/201 282 PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image1.jpg proxyuser DIRECT/172.26.27.22 - 
1352370542.033  7 172.26.27.94 TCP_MISS/201 282 PUT http://172.26.27.22:8080/myapp/rest/2/3/29/image2.jpg proxyuser DIRECT/172.26.27.22 - 

답변

0

그것은 당신의 AuthScope의 : 위 내 댓글에

// You set proxyServer here vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
credsProvider.setCredentials(new AuthScope(proxyServer, proxyPort), new UsernamePasswordCredentials(proxyUser, proxyPassword)); 
httpClient.setCredentialsProvider(credsProvider); 
// But here you are looking for the indexof https to determine if it is an SSL proxy 
// is the String returned from getProxyServer() above a URL or a host name? 
HttpHost proxy = new HttpHost(proxyServer, proxyPort, (proxyServer.indexOf("https") != 0) ? "http" : "https"); 
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); 

를 묻혀 - 문자열이 getProxyServer() URL 또는 호스트 이름에 의해 반환?

편집

나는 내가 무슨 일이 일어나고 있는지 알아 낸 것 같아요. Basic Auth는 요청할 때마다 보내야합니다. 여러 번 실행하는 경우 인증 데이터를 캐시 할 수있는 메커니즘이 필요합니다. 당신이 지금 당장 유행하던 방식으로 클라이언트를 실행함으로써, 모든 요청에 ​​대해 생성되는 것을 저장할 수있는 "컨텍스트"가 존재하지 않습니다.

다른 항목은섹션 4.7과 4.8입니다. BASIC 인증 요청에 이어 407 오류를 완전히 제거하려면 4.8 절을 읽으십시오.

그들이 정의한 "localcontext"변수는 클라이언트의 상태 컨테이너 역할을하므로주의하십시오.

+0

getProxyServer은() – Lazy

+0

재미있는 ...이 IP 주소를 반환 당신은 http/https 점검없이 HttpHost를 시도 했습니까? 그게 어떤 영향을 미칠지 궁금하네요. 그건 제쳐두고, 내가 구성되어있는 프록시를 사용하려고 시도하는 경우에도 디버거를 사용하여 추적하려고합니다. –

+0

예, http/https없이 시도했지만 결과는 같습니다. – Lazy

5

HTTP 프록시를 사용한 인증 프로세스는 RFC2616 §14.33과 14.34에 설명되어 있으며 HttpClient에서 보는 것과 동일합니다.그것은 포함

  • 407 (프록시 인증 필요) 요구 된 자원에 적용 할 수있는 도전을 포함하는 프록시 인증합니다 헤더 응답을 전송 프록시하는로 새 요청을 발행
  • 클라이언트 프록시 인증 헤더는 인증 정보가 들어있는 자격 증명으로 구성됩니다.

HttpClient로 선점 인증을 구현하는 방법은 this tutorial (§4.8 절)에 설명되어 있으며 클라이언트 개체의 인증 캐시를 미리 채워야합니다. 아쉽게도 프록시 서버를 사전 인증 할 때 코드가 작동하지 않습니다. 그것을 제대로하는 방법을 이해하기 조금 까다로운 일이 될 수 있지만, 실제로는 BasicScheme 생성자에 매개 변수를 전달하는 것만 큼 간단하다 :

AuthCache authCache = new BasicAuthCache(); 

AuthScheme basicAuthScheme = null; 
if (isProxy) { 
    basicAuthScheme = new BasicScheme(ChallengeState.PROXY); 
} else { 
    basicAuthScheme = new BasicScheme(ChallengeState.TARGET); 
} 

authCache.put(host, basicAuthScheme); 
httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache);