Creating a WCF Service Reference to a Secured Service
I have a WCF service I created that is secured over HTTPS using client certificates. How I got my client talking to this service was easy, I just created a service reference using Visual Studio to my service. Simple, right? Well it was until I needed to update my reference. You see, I initially created my service reference before I secured my service. So I was talking to an unsecured service over HTTP. However, what happens when that security changes? Well, what I did was just change the URL to the secure one and everything worked fine until I needed to update the implementation of my service proxy. When you need to do that, the service reference tool in Visual Studio will no longer cut it.
The documentation provided by Microsoft will show you how to create a service reference to a secured service. The following is a reprint of the section for creating the service reference since the entire MSDN article takes you through creating the certs from the ground up. This article assumes that you already have a working service and client that are communicating with client certificates over HTTPS.
- In your service’s web.config enable your MEX endpoint:
- The first thing you should notice is that the binding configuration for both the service and the mex endpoint use the same configuration. This configuration is what specifies that these endpoints will be using certificates over HTTPS.
- Now that we have the mex endpoint setup on the service, we can start working on the client reference. Create yourself a new temp directory that you can work in to create the new service reference.
- In this dir create a new text file named svcutil.exe.config.
- Paste the following into the contents of this file:
- Modify the clientCertificate node to match the client certificate that you already have specified in your client config.
- Create the service proxy
- Copy svcutil.exe into the temp directory you are working in so that the exe will use the custom config you just created. (Copy in the exe? I know this sounds dumb, but this is what the MSDN documentation says to do. Not wanting to do this I tried to just point svcutil.exe to my new config
- Execute:
- This will create 2 files: an app.config and a service proxy (*.cs) file.
- Now you can go to your client application and remove any existing service reference that you have.
- Compare your existing client app.config to the one we just created and merge the new one into the existing one as appropriate. I can’t really tell you what to do beyond this aside from telling you to manually diff these since your implemenation may be different from mine.
- Copy the .cs file into your client project. Check the namespacing of this file. Mine didn’t wrap the service interface in the namespace properly when mine was generated.
- At this point you should be able to test your changes. You should now be executing on the new proxy we created communicating securely to your service.
svcutil https://ServerName/WCFTestService /config:app.config
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="WsBindingConfig" contract="IISServicePOC.IService1"></endpoint> <endpoint address = "mex" binding = "wsHttpBinding" bindingConfiguration="WsBindingConfig" name="mexEndpoint" contract = "IMetadataExchange"/>
<configuration> <system.serviceModel> <client> <endpoint behaviorConfiguration="ClientCertificateBehavior" binding="wsHttpBinding" bindingConfiguration="Binding1" contract="IMetadataExchange" name="https" /> </client> <bindings> <wsHttpBinding> <binding name="Binding1"> <security mode="Transport"> <transport clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="ClientCertificateBehavior"> <clientCredentials> <clientCertificate findValue="CN=clienttempcert" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectDistinguishedName" /> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration>