When both the proxy server and the web server need authentication, the client fails. The testing environment is a Windows domain with an ISA and an IIS. Both NTLM and Negotiate fails.
Take NTLM for example, the dialog looks like:
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )
Proxy-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
## Response: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
** GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
Authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
FINE: >>>> FAILED
At the ## response shows, the proxy authentication already succeeds, and we're faced with WWW authentication. However, in the ** request, the client sends both the Proxy-authorization header and the Authorization header to the proxy, and the proxy prompts for another Proxy-Authenticate.
The Proxy-authorization header inside the ** request should be a bug. The header is simply a duplicate of the same header in the previous request because we didn't clean up the request headers.
In order to avoid this, I update HttpUrlConnection.java to remove any Proxy-authorization header and the Authorization header after the request is sent (I know this may not be a nice solution because for Basic authentication we can remember the header), and then the dialog goes into:
FINE: >>>> http://k1.n3.local:81/haha.txt
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )
Proxy-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
## Response: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
** GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
FINE: >>>> FAILED
As we can see, although the ** request only sends the WWW authorization header, the proxy is asking for Proxy-Authenticate again.
Thus I think it's because we've closed the connection after we get the ## response. I substitute the 2 disconnectInternal() calls inside the "if (respCode == HTTP_UNAUTHORIZED)" block into a simple "responseCode = -1", and now it succeds.
FINE: >>>> http://k1.n3.local:81/haha.txt
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
null: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
null: HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )
Proxy-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
null: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Authorization: NTLM T...
null: HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Authorization: NTLM T...
null: HTTP/1.1 200 OK
FINE: >>>> OK
Take NTLM for example, the dialog looks like:
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )
Proxy-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
## Response: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
** GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
Authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
FINE: >>>> FAILED
At the ## response shows, the proxy authentication already succeeds, and we're faced with WWW authentication. However, in the ** request, the client sends both the Proxy-authorization header and the Authorization header to the proxy, and the proxy prompts for another Proxy-Authenticate.
The Proxy-authorization header inside the ** request should be a bug. The header is simply a duplicate of the same header in the previous request because we didn't clean up the request headers.
In order to avoid this, I update HttpUrlConnection.java to remove any Proxy-authorization header and the Authorization header after the request is sent (I know this may not be a nice solution because for Basic authentication we can remember the header), and then the dialog goes into:
FINE: >>>> http://k1.n3.local:81/haha.txt
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )
Proxy-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
## Response: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
** GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Authorization: NTLM T...
Response: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
FINE: >>>> FAILED
As we can see, although the ** request only sends the WWW authorization header, the proxy is asking for Proxy-Authenticate again.
Thus I think it's because we've closed the connection after we get the ## response. I substitute the 2 disconnectInternal() calls inside the "if (respCode == HTTP_UNAUTHORIZED)" block into a simple "responseCode = -1", and now it succeds.
FINE: >>>> http://k1.n3.local:81/haha.txt
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
null: HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires autho
rization to fulfill the request. Access to the Web Proxy service is denied. )
Proxy-Authenticate: NTLM
Proxy-Authenticate: Kerberos
Proxy-Authenticate: Negotiate
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
null: HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )
Proxy-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Proxy-authorization: NTLM T...
null: HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Authorization: NTLM T...
null: HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM T...
GET http://k1.n3.local:81/haha.txt HTTP/1.1: null
Authorization: NTLM T...
null: HTTP/1.1 200 OK
FINE: >>>> OK