In my corporate environment there is a transparent proxy that requires credentials for internet access (every four hours). In my application I successfully passed credentials like this:
var client = new WebClient();
client.Credientals = new NetworkCredential("username", "password");
string result = client.DownloadString("http://...");
// this works!
However, when my intial request is to a "https://" url, there is an Exception throw: "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
Now my current work around is to:
- catch the WebException thrown when accessing the "https://" url
- add my Credentials to a new request to an arbitrary "http://" site
- (this should "open up" the internet for a four hour window)
- go back and re-try the "https://" request
I am wondering if there is a better/cleaner way to do this?
What you are using right now is an HTTP proxy with authentication. So far so good. But it won't work for HTTPS requests, and here's why:
SSL/TLS is endpoint security. This means that the data must be sent between the client and the server via the single encrypted channel.
When you connect to the HTTP proxy, you tell it "GET the remote resource and send it to me", which contradicts to endpoint security. Here you don't have direct connection to the remote server and you can't validate its credentials. Also the proxy can peep into your data.
In general, it's possible to connect to regular HTTP proxy using HTTPS OR it is possible to ask the HTTP proxy to access HTTPS resource, but this breaks security cause in both cases the client can't validate server's credentials and HTTP proxy can log or alter the data being transferred.
HTTPS proxy works in a different way. Here you tell the HTTPS proxy server "CONNECT to remote address and then only resend whatever is passed". This way the proxy creates an opaque secure channel between the client and the server thus preserving endpoint security. Actually, HTTPS proxy can be used to tunnel any traffic, not necessarily SSL.
Consequently you need to establish the tunnel by sending CONNECT request (with your authentication included), and then send regular HTTP GET (without host/address in the URL) over the same channel - this request will go to the destination server, not to the proxy.
I have serious doubts that your WebClient can be made to establish a tunnel before sending a request. As an option, you can use HTTPBlackbox package of our SecureBlackbox product which lets you access HTTP and HTTPS resources, and supports HTTPS proxies (called WebTunneling in SecureBlackbox) with authentication.