WCF Proxy Server Authentication

Many who've written a .NET application which calls a web service have had to deal with service calls passing through a proxy server. In the past, after generating the service client from WSDL, I’d set up a WebProxy (possibly with NetworkCredential) — which really isn’t all that bad, but somewhat annoying. Now, more ideally, the service calls are via svcutil generated WCF clients. However, handling proxies programmatically in WCF is more difficult since you can’t deal with a nice WebProxy object. You can set credentials via ChannelFactory.Credentials, but this has a drawback — your credentials need to be the same for the proxy and server authentication if they both use the same authentication scheme. The programmatic approach has always struck me as unnatural.

I just discovered a much simpler way to deal with proxies this week. Thankfully, the answer really has nothing to do with WCF. WCF depends on the underlying System.Net subsystem, and by default, .NET clients will not pass their credentials to the default proxy server. This is what had tripped me up in the past. The default errs on the side of security, since you may not want to leak credentials when not necessary. You can instruct System.Net to pass the default credentials via the following config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <defaultProxy useDefaultCredentials="true" />
  </system.net>
</configuration>

If your application is running as a domain user who has access to the proxy server, your WCF, web service, etc. calls will work without further modification. As a matter of practice, I configure my Application Pool identities and Windows Service identities to run under domain user accounts whenever possible.

Sometimes you may need to specify your default proxy if the system cannot autodetect it or you don’t want to use the autodetected proxy. In that case you can do the following (this example also uses default credentials as above):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <defaultProxy useDefaultCredentials="true">
      <proxy usesystemdefault="false" proxyaddress="http://[proxy server]" bypassonlocal="true" />
    </defaultProxy>
  </system.net>
</configuration>

Using default credentials works in all the situations I’ve encountered, but you may run into the need to specify different credentials in shared hosting environments/etc. To my knowledge, there’s no way to specify particular credentials in .NET configuration files. If you need to specify other credentials for your web proxy and you’re using WCF, you’re stuck specifying them via ChannelFactory.Credentials on your WCF client.