I had to work extensively in this topic, and had to go through hundreds of blogs and articles to finally make it work. It’s actually pretty simple but for someone who is new to WCF, it might give a few sleepless nights and some terrible days.
This article assumes that you have a decent knowledge on WCF, IIS hosted WCF Services, transport security and digital certificates.
Configuring the Service:
Open your Service’s web.config file and edit it’s binding configuration as below:
<bindings> <wsHttpBinding> <binding name="CertificateWithTransport"> <security mode="Transport"> <transport clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings>
The above binding configuration uses wsHttpBinding with Transport mode security. You can also notice that the clientCredentialType is mentioned as “Certificate”. It means, that the consumer of the service is authenticated using a certificate.
Your behavior section should look like this,
<serviceBehaviors> <behavior name="BindingBehavior"> <serviceMetadata httpsGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/>
</behavior> </serviceBehaviors>
Notice that the httpsGetEnabled=”true” attribute. It tells WCF to serve get request on the service. This is should be set to true when you want the consumers to get the wsdl themselves.
If this is set to false, no one will know about this service, unless you give them the wsdl file for consumption. Most of the enterprise services do set this attribute to false for security reasons.
Your Services section should look like this,
<services> <service behaviorConfiguration="BindingBehavior" name="servicename"> <endpoint binding="wsHttpBinding" contract="SSPNotificationReceiver.IReceiverService" bindingConfiguration="CertificateWithTransport"> </endpoint> <!--<endpoint address="mex" binding="mexHttpsBinding" name="MetadataBinding" contract="IMetadataExchange"/>--> </service> </services>
The above behavior configuration basically exposes an endpoint with information about the binding type, service contract type and the binding configuration. The bindingConfiguration attribute is the link between the binding settings and the endpoint, and the behaviorConfiguration attribute is the link between the behavior settings and the service settings.
The commented endpoint is for the meta data exchange. Since we are using SSL, the meta data exchange is also secure. But beware, may be this is the most important statement in the entire article. There is something very important about commenting this part at the end of the article.
Setting up IIS and creating the Certificates:
Now, publish the service on IIS using Visual Studio. The following screen shots show you how to configure the IIS SSL mappings.
The following example will show you how to create SSL Server and SSL client certificates using a Certificate Authority running on Windows Server 2003. You can also create your own certs for development through makecert.exe. There are multiple articles on the internet showing how to create certificates using the tool. Just do a Live Search and find out.
With this, you have successfully created the SSL Server Certificate which can be used for Server Authentication purpose.
Follow these steps to create a Client Authentication certificate.
Configuring IIS for 2 Way SSL Authentication
Do not do the following steps if your service needs only SSL Server Authentication. To enable SSL Client authentication also, proceed with the following steps
Configuring the client to use SSL
<system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IReceiverService"> <security mode="Transport"> <transport clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address=https://YourIP/ReceiverHost.svc behaviorConfiguration="credentialConfiguration" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IReceiverService" contract="NotificationProxy.IReceiverService" name="WSHttpBinding_IReceiverService" /> </client> <behaviors> <endpointBehaviors> <behavior name="credentialConfiguration"> <clientCredentials> <clientCertificate findValue="99bbc6c9e6f4a6bd526bc8bb21f9c21f0716c23r" storeLocation="CurrentUser" x509FindType="FindByThumbprint" />
</clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
I have pretty much posted the entire client configuration here. There is nothing very different from the service configuration, but for the behavior and the endpoint address.
Now, you are all set to access the service through the client.
You can access the service using the browser too..
When you do so, the browser (IE) pops up a window showing all the certificates installed in your personal store. You need to select a the certificate that you already installed in it
Select the appropriate certificate to view the service screen.
That’s it. Your service is up and running on IIS, secured using 2 Way SSL Authentication.
Two most important things not to forget:
As I said earlier there are two things that you should do:
NEVER FORGET TO ENABLE ANONYMOUS ACCESS ON IIS.
NEVER FORGET TO COMMENT THE MEX ENDPOINT ON THE SERVICE CONFIG
These two things are the most crucial part of this entire process. WCF, for some reason that I don’t know, wants Anonymous Access to be enabled on the website. You will get this error if you don’t do so.
Exception: System.ServiceModel.ServiceActivationException: The service '/ReceiverHost.svc' cannot be activated due to an exception during compilation. The exception message is: Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.. --->
Next, if you forget to leave the mex endpoint uncommented, you might end up seeing this error on the event log of the service.
Exception: System.ServiceModel.ServiceActivationException: The service '/ReceiverHost.svc' cannot be activated due to an exception during compilation. The exception message is: The SSL settings for the service 'None' does not match those of the IIS 'Ssl, SslNegotiateCert, SslRequireCert, SslMapCert'.. –->
As you can see, this does not convey any reasonable thing to you, leave alone suggestions to fix the error. Be careful with these two settings.
Enjoy WCF !!