Externalize your Communication Protocol Details with WCF

In general the Web Service client proxy generated by “Add Web Reference” in Visual Studio is all you need to start talking to a Web Service. Some of you may need to present a certificate to the remote server you are calling and for this purpose you would typically populate the ClientCertificates collection on the generated proxy class like:

WebServiceProxy prx = new WebServiceProxy();

X509Certificate certificate = FetchRelevantCertificate();

prx.ClientCertificates.Add(certificate);

prx.SomeMethod();

The fictitious method FetchRelevantCertificate finds the relevant certificate using the X509Store class or a similar wrapper. While this is probably what many of us have done in the past it adds an unfortunate coupling to the communication protocol in your compiled code.

 

As you probably know WCF allow you to configure almost anything relevant for the communication externally to the code in the System.ServiceModel configuration section. The equivalent code using a WCF generated (svcutil.exe) client proxy would be:

WebServiceProxy prx = new WebServiceProxy();

prx.SomeMethod();

 

Nothing here specifies the need of a client certificate for the communication. For the code to actually present the required certificate you should simply add the following (or similar) section to your app.config (or web.config):

  <system.serviceModel>

    <behaviors>

      <endpointBehaviors>

        <behavior name="ClientSecureBehavior">

          <clientCredentials>

            <clientCertificate

              findValue="MyCertificate"

              storeLocation="CurrentUser"

              storeName="My"

              x509FindType="FindBySubjectName" />

          </clientCredentials>

        </behavior>

      </endpointBehaviors>

    </behaviors>

    <bindings>

      <basicHttpBinding>

        <binding name="ClientSecureBinding">

          <security mode="Transport">

            <transport clientCredentialType="Certificate" />

          </security>

        </binding>

      </basicHttpBinding>

    </bindings>

    <client>

      <endpoint address="https://demoappserver.mydomain.local/SSLTest/Service.asmx"

          binding="basicHttpBinding"

          bindingConfiguration="ClientSecureBinding"

          behaviorConfiguration="ClientSecureBehavior"

          contract="MyContractHere">

      </endpoint>

    </client>

  </system.serviceModel>

As you see this gives you complete isolation of business code and communication protocol related code. I agree that you could build a similar externalization for the wsdl.exe generated proxy classes, but with WCF this is really plain vanilla. As a side note you obviously do not have to change anything on the server side to start using WCF clients. In short: svcutil.exe is your friend ;-)

Nothing new really - I just got excited about this point late last week.