By Lance Livingston, on July 22nd, 2013
I was building a Silverlight 2.0 application for a client and determined that it was appropriate to utilize SSL to secure the site. In particular, to secure communications back-and-forth between the WCF services which were handling a lot of sensitive financial data. Although I had setup SSL on several sites before, I didn’t realize how difficult it was to find a good reference on how to do this for WCF. After a very long day, thought I’d share how I got this to work. Of course, now that I know, it’s not that tough.
1. Install your SSL Certificate
I’m not going into the details on how to setup SSL in IIS7 here other than to say ASPHostPortal.com is awesome. They’re cheap (in a good way) and for those of you who need a little extra help, they’ve got really easy instructions on how to get your cert up and running in a hurry.
2. Configure your WCF Service
In order for a service to communicate over SSL, a few adjustments must be made to your service’s web.configsettings that VS.NET will setup for you by default. Here’s how I set mine up. I’ve highlighted a couple of the enhancements that were important to getting the service to run properly. In particular, the specification of the “transport” security binding tells the service to utilize secure communication.
<system.serviceModel>
<services>
<service behaviorConfiguration=”Namespace.MyServiceBehavior” name=”Namespace.MyService”>
<endpoint address=”https://www.tricension.com/MyService.svc” binding=”basicHttpBinding”bindingConfiguration=”Binding” contract=”Namespace.IMyService”/>
<host>
<baseAddresses>
<add baseAddress=”https://www.tricension.com/MyService.svc”/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name=”Namespace.MyServiceBehavior”>
<serviceMetadata httpsGetEnabled=”true”
httpsGetUrl=”https://www.tricension.com/MyService.svc” />
<serviceDebug includeExceptionDetailInFaults=”true” />
</behavior>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name=”Binding”>
<security mode=”Transport”>
<transport clientCredentialType=”None”/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
Oh, you probably know this already (pretty well documented), but just in case…Silverlight 2.0 applications only support basicHttpBinding. VS.NET will not set this option by default, so make sure you change it or your service reference will not add correctly.
3. Test the service
I found that trying to troubleshoot services from the Silverlight client can be a bit tricky. Once the configuration is setup, I recommend you open up the service definition in a browser and validate that the service comes up correctly before moving on.
4. Configure the Silverlight Client
When WCF services are added as references in a Silverlight 2.0 project, VS.NET 2008 will create a file called ServiceReferences.clientconfig which defines the service endpoints that the client is consuming. If you setup your service from the beginning using SSL, VS.NET will add the proper settings in this file to communicate over SSL. If you are like me, you don’t use SSL anywhere but production (and sometimes test). In this case, the original end point configuration must be changed upon moving to the secure environment.
Similar to the service configuration, the client specifies a security binding of “transport”.
<bindings>
<basicHttpBinding>
<binding name=”BasicHttpBinding_IMyService” maxBufferSize=”2147483647″ maxReceivedMessageSize=”2147483647″>
<security mode=”Transport” />
</binding>
</basicHttpBinding>
</bindings>
The definition of the endpoints is basically the same, with the exception of the https:// designation in the URL.
<client>
<endpoint address=”https://www.tricension.com/MyService.svc”
binding=”basicHttpBinding”
bindingConfiguration=”BasicHttpBinding_IMyService”
contract=”Namespace.IMyService” name=”BasicHttpBinding_IMyService” />
</client>
5. Cross-domain Support
In the event your application requires cross-domain support, you will also have to modify the clientaccesspolicy.xmlfile to something like this:
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers=”*”>
<domain uri=”http://*”/>
<domain uri=”https://*”/>
</allow-from>
<grant-to>
<resource path=”/” include-subpaths=”true”/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>