10

I'm working on a .NET app that calls 3rd party web services over the internet. The services do not use SOAP, so we manually construct an XML request document, send it to the service via HTTP, and retrieve an XML response.

Our code is a Windows service that is run in the context of a normal Windows domain account, and sits behind a proxy server (Microsoft ISA Server) configured to require NTLM authentication. The account running our service has permission to access the internet through the proxy server.

The code looks like this:

// Create the request object.
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";

// Configure for authenticating proxy server requiring Windows domain credentials.
request.Proxy = New WebProxy(proxyAddress) { UseDefaultCredentials = true };

// Set other required headers.
request.Accept = acceptableMimeType;
request.Headers.Add(HttpRequestHeader.AcceptCharset, acceptableCharset);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "none");
request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-gb");
request.Headers.Add(HttpRequestHeader.CacheControl, "no-store");
request.Headers.Add(HttpRequestHeader.ContentEncoding, "none");
request.Headers.Add(HttpRequestHeader.ContentLanguage, "en-gb");
request.ContentType = requestMimeType;
request.ContentLength = requestBytes.Length;

// Make the method call.
using(Stream stream = request.GetRequestStream()) {
    stream.Write(requestBytes, 0, requestBytes.Length);
}
HttpWebResponse response = (HttpWebResponse) request.GetResponse();

// Extract the data from the response without relying on the HTTP Content-Length header
// (we cannot trust all providers to set it correctly).
const int bufferSize = 1024 * 64;
List<byte> responseBytes = new List<byte>();
using(Stream stream = new BufferedStream(response.GetResponseStream(), bufferSize)) {
    int value;
    while((value = stream.ReadByte()) != -1) {
        responseBytes.Add((byte) value);
    }
}

This works fine if the proxy server is turned off, or the URL has been whitelisted as not requiring authentication, but as soon as authentication is active, it always fails with an HTTP 407 error.

I put the above code in a test harness, and tried every method I could think of for configuring the request.Proxy property, without success.

I then noticed that all the 3rd party web services that we have to call are HTTPS. When I tried accessing them as HTTP instead, the proxy authentication started working. Is there some extra hoop I have to jump through to get proxy authentication and HTTPS to play nicely?

PS: The same problems occur with the open source SmoothWall proxy server, so I can't just write it off as a bug in ISA Server.

PPS: I'm aware that you can configure proxy settings in app.config, but (a) doing it in code shouldn't make any difference, and (b) the application design requires that we read the proxy settings from a database at runtime.

Christian Hayter
  • 30,581
  • 6
  • 72
  • 99

4 Answers4

13

Have you tried setting the proxy in the app.config ?

To disable the proxy, in the App.config file add the following configuration

<system.net>
  <defaultProxy enabled="false" useDefaultCredentials="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

To enable the proxy and to use the default proxy settings(specified in IE) add this configuration in your App.config

<system.net>
  <defaultProxy enabled="true" useDefaultCredentials="true">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>
abhilash
  • 5,605
  • 3
  • 36
  • 59
3

I did have a similar situation

Did you noticed it worked when you accessed the internet before you ran the code? and if you had not accessed the internet for ages (20mins for me) you got the error.

have you tried to set the proxy credentials directly?

//setup the proxy
request.Proxy = new WebProxy("proxyIp", 8080);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;

I hope this fixes your issue too

dbones
  • 4,415
  • 3
  • 36
  • 52
  • Hi Dbones, thanks for sharing your experience! Unfortunately I have observed the proxy server failing suddenly even after successful connections were made only a few seconds earlier. Also I have indeed tried that exact method of defining the proxy in code, and it made no difference. – Christian Hayter Oct 03 '10 at 09:54
  • wow, i hate to say, but the above fixed my issue. I hope you can find a resolution for your situation – dbones Oct 03 '10 at 18:30
1

I think I will have to write off this question. My original posted code does appear to work sometimes. Our proxy server is extremely unreliable; one minute it will block an internet connection from any software, and the next it will allow it. The IT guys seem powerless to do anything about it, and we (everyone outside the IT department) have no authority to make changes to the network infrastructure.

If anyone has any ideas on how to "harden" my code to compensate for an unreliable proxy server, then I'd be interested to hear them. :-)

Christian Hayter
  • 30,581
  • 6
  • 72
  • 99
  • that is what exactly happens in my case.some time i have able to connect without this error. – Kamran Shahid May 24 '13 at 05:36
  • 3
    Posting as Troubleshooting tip for those that stroll across this: It could be the proxy server config/software, but the first check in intermittent issues like this is eliminate partial cluster failure. If there are multiple proxy servers behind a load balancer, and only one is configured properly, you'll only get through when balanced to the "good" instance, aka. sometimes. – Barryrowe Nov 17 '14 at 17:39
0

Is there something wrong with your proxy server's certificate? If your service can't establish HTTPS then it will throw an error.

AUSteve
  • 3,238
  • 21
  • 36
  • I have asked our IT admins about this, and they say that it is definitely configured to support SSL. They successfully browsed to an HTTPS web site via the proxy server. – Christian Hayter Jan 26 '10 at 08:53