In my previous post, I started talking about SSL and how important certificates are for SSL infrastructure. In this blog I will talk about implementing SSL in a WCF web service.
Before we start anything, please make sure you have a root certificate and a developer certificate as explained in this article. That article also talks about implementing SSL in WCF but I could not get it to work with just the steps in this article. I had to do a couple of other things as well.
Implementing SSL in WCF web service is all about configuration. You will find several tutorials on the web on how to create a simple WCF service, like the one here, here and here so I am not going to go into that. I am using Visual Studio 2010 to create a WCF service and implement SSL in it.
Once you have a WCF service project in Visual Studio 2010, open the web.config file. Almost everything you need to do to get your web services to use SSL goes here. Here is my complete web.config file:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WCFWithSSL_2.WCFSampleService"
behaviorConfiguration="MyServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost/WCFWithSSL_2/"/>
</baseAddresses>
</host>
<endpoint address="Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="TransportSecurity"
contract="WCFWithSSL_2.IWCFSampleService" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<!--<behavior>
--><!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata
endpoint above before deployment --><!--
<serviceMetadata httpsGetEnabled="true"/>
--><!-- To receive exception details in faults for
debugging purposes, set the value below to true.
Set to false before deployment to avoid disclosing
exception information --><!--
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>-->
<behavior name="MyServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I have highlighted the relevant pieces. Arguably, the most important configuration piece is the “binding” tag. We specific the “security mode” property as “Transport”. This specifies that we want to use SSL. The other vital piece of configuration is the “behavior” where we set the “httpsGetEnabled” property to “true”.
This binding and behavior are then imposed on our service under the “services” tag with the bindingConfiguration and behaviorConfiguration properties.
Finally the endpoint tags specify the actual service on which you would like to impose SSL transport encryption.
You will find that there are two endpoint tags. In the endpoint with the “mex” address, it is important to specify that its binding is HTTPS as well using the “mexHttpsBinding” property value.
In the other endpoint tag, I was not able to get the service working by specifying the service URL completely in the “address” property. I had to create a “baseAddresses” tag and specify a base address and then specify the service address relative to the base address in the endpoint.
These settings *almost* do everything I need but they were not enough. I had to go the the project properties and under the “Web” tab, I had to explicitly specify that Local IIS Web Server as the server to be used for testing:
That is it. I am now able to browse to the service URL:
Just like you would with an unencrypted service:
Also, here is the source of the sample service I created.
Comments
You can follow this conversation by subscribing to the comment feed for this post.