We have a javascript application that uses OAuth to speak to some of our backend web services. Everything worked fine in our test environment, but when accessed from the customer site we were having intermediate problem where the OAuth authenticated requests (they were XHR requests) were being denied. This turned out to be happening because the Authorization headers that were suppose to contain the OAuth parameters were sporadically being dropped. Mind you the customer was using IE6, however we had tested the application onIE6 prior to that and we had not experienced such behaviour. With no way to simulate the problem offsite we had to go onsite.
At the client sites it was discovered that their Internet connectivity was behind a corporate proxy. Thanks to the great IE plugin iehttpheaders by Blunk Software we were able to look at the request and responses headers on the browser.
Request 1
This is the request after completing the OAuth dance. Notice the OAuth parameters in the Authorzation headers.
GET http: //somehost.com/someapp/index?some_value=some_query HTTP/1.0 Accept: application/json, text/javascript, */* Accept-Language: en-us Referer: http://somehost.com/test.html Authorization: OAuth realm="http://somehost.com/",oauth_consumer_key="key", oauth_token="0ca1a675c6bb4ae394069b3e240b6197",oauth_signature_method="HMAC-SHA1",oauth_signature="HgGi6izQbRPnDaoarKkk2itfg4s=", oauth_timestamp="1235464028",oauth_nonce="bzSgtifUd6",oauth_version="1.0" x-requested-with: XMLHttpRequest User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 2.0.50727) Host: somehost.com Proxy-Connection: Keep-Alive
Response 1
Many requests like this might of preceded this particular requests successfully. However this requests happens at the point where (we believe) the proxy session has expired. Hence we get a challenge from the proxy.
HTTP/1.1 407 Proxy Authentication Required Proxy-Authenticate: NTLM Proxy-Authenticate: BASIC realm="Bobo Domain Username and Password" Cache-Control: no-cache Pragma: no-cache Content-Type: text/html; charset=utf-8 Proxy-Connection: close Set-Cookie: BCSI-CS-863E59BB9B98BEDA=2; Path=/ Connection: close Content-Length: 813
Request 2
The browser responds to the authentication challenge. By this point the Authorization header has been dropped. The reason why however is lost to me as the Proxy Authentication doesn’t use that header.
GET http: //somehost.com/someapp/index?some_value=some_query HTTP/1.0 Accept: application/json, text/javascript, */* Accept-Language: en-us Referer: http://somehost.com/test.html Cookie: BCSI-CS-863E59BB9B98BEDA=2; __utmc=65970999; x-requested-with: XMLHttpRequest Proxy-Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFASgKAAAADy== User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 2.0.50727) Host: somehost.com Proxy-Connection: Keep-Alive
Response 2
The server responds with a success.
HTTP/1.1 407 Proxy Authentication Required Proxy-Authenticate: NTLM TlRMTVNTUAACAAAACAAIADgAAAAFgomimskXX4CIQeAAAAAAAAAAAIYAhgBAAAAABQLODgAAAA9LAFIARgB UAAIACABLAFIARgBUAAEAGgBLAEYAVABBAFUAQgBVAFIAUABYAFIAMAAxAAQAEABLAFIARgBUAC4ATgBlAHQA AwAsAGsAZgB0AGEAdQBiAHUAcgBwAHgAcgAwADEALgBLAFIARgBUAC4ATgBlAHQABQAQAEsAUgBGAFQALgB OAGUAdAAAAAAA Cache-Control: no-cache Pragma: no-cache Content-Type: text/html; charset=utf-8 Proxy-Connection: Keep-Alive Set-Cookie: BCSI-CS-863E59BB9B98BEDA=2; Path=/ Connection: Keep-Alive Content-Length: 830
Request 3
The initial request is made again however now without the Authorization heder.
GET http: //somehost.com/someapp/index?some_value=some_query HTTP/1.0 Accept: application/json, text/javascript, */* Accept-Language: en-us Referer: http://somehost.com/test.html Cookie: BCSI-CS-863E59BB9B98BEDA=2; __utmc=65970999; x-requested-with: XMLHttpReques Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGYAAAAYABgAfgAAAAgACABIAAAADgAOAFAAAAAIAAgAXgAAAAAAAACWAAAA BYKIogUBKAoAAAAPawByAGYAdABrAGEAcAB2AHgAbQAwAEsAWQBBAFAAWV5DPMLLAQwAAAAAAAAAAAAAA AAAAAAAmZQUP+OrhQJTr8sGO5WtLNI7QyxHr8li User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 2.0.50727) Host: somehost.com Proxy-Connection: Keep-Alive
Response 3
And it fails.
HTTP/1.1 403 Request type not available Date: Tue, 24 Feb 2009 08:27:06 GMT Server: Someserver Vary: Accept-Encoding,User-Agent Content-Type: application/x-json Content-length: 63 Proxy-Connection: Keep-Alive Connection: Keep-Alive
Summary
This type of behavior is odd for couple of reasons
- We don’t experience this in Firefox. Firefox correctly continues to pass the Authorization header in Request 3
- The Authorization header is not even used in the Proxy Authentication process.
- If we were to use some other header say X-Authorization (I know, I know
) the header comes out fine in Response 3.
This type of bizzare behaviour makes it even more critical that service providers ensure that all parameter transmission methods are implemented.