WCF Web Services, HTTPS, Message Security, Transport Security, Certificates

This is more complex than it should be, but we as developers work with what we got.  There are a lot of moving parts, and this is a collection of links and notes to help one navigate the minefield of secure web services.
 If you are on a dev machine, you need to get test certificate.  Microsoft has a utility "makecert" that can help with it.  Another option is to get a free, temporary one from a provider such as Verisign (http://www.verisign.com/) and follow their instructions.  http://www.codeplex.com/WCFSecurity/Wiki/View.aspx?title=How%20To%20-%20Create%20and%20Install%20Temporary%20Certificates%20in%20WCF%20for%20Message%20Security%20During%20Development&referringTitle=How%20To%20-%20Use%20Certificate%20Authentication%20and%20Message%20Security%20in%20WCF%20calling%20from%20Windows%20Forms has some good details on managing the cert.
Note, I am not a cert expert, and there may be issues with the differences between the 2 type of certs.  
One handy tool in all of this is the MMC snap-in for certificate management (per codeplex):
  1. Click Start and then click Run.**
  2. In the command line, type MMC and* then* click OK.
  3. In the Microsoft Management Console, on the File menu, click Add/Remove Snap-in.
  4. In the Add Remove Snap-in dialog box, click Add.
  5. In the Add Standalone Snap-in dialog box, select Certificates and then click Add.
  6. In the Certificates snap-in dialog box, select the Computer account radio button because the certificate needs to be made available to all users, and then click Next.
  7. In the Select Computer dialog box, leave the default Local computer: (the computer this console is running on) selected and then click Finish.
  8. In the Add Standalone Snap-in dialog box, click Close .
  9. In the Add/Remove Snap-in dialog box, click OK .
 Speaking of Codeplex, there are some good step-by-steps for setting up the Web Service.  I essentially used this one, customizing it for Username (custom) authentication: http://www.codeplex.com/WCFSecurity/Wiki/View.aspx?title=How%20To%20-%20Use%20wsHttpBinding%20with%20Username%20Authentication%20and%20TransportWithMessageCredential%20in%20WCF%20calling%20from%20Windows%20Forms&referringTitle=How%20Tos
 The critical points are:

Step 4 – Create a Sample WCF Service Project with SSL

In this step you will create a WCF service in Visual Studio and enable SSL.

  1. In the Visual Studio, select File -> New Web Site
  2. In the Templates section select WCF Service. Make sure that the Location is set to Http and then click Browse button.
  3. In the Choose Location dialog box, click Local IIS.
  4. Check the Use Secure Sockets Layer check box at the bottom of the dialog box, and then click Open button.
  5. In the New Web Site dialog box, set the new Web site address as https://localhost/ WCFTestService and then click Ok button.

Note: SSL port might not be configured by default on the IIS, so while creating the WCF service it might throw errors. Open the IIS manager and right click the Default Web Site and choose Properties option. In the Default Web Site Properties dialog box, click the Web Site tab make sure the SSL port: is set to "443".

Step 5 – Configure the Virtual Directory to Require SSL

In this step you will configure the virtual directory hosting the Service to use SSL.

  1. Click Start then Run and in the command box type inetmgr and click OK to open the Internet Information Services manager.
  2. In the Internet Information Services Manager dialog box, expand the (local computer) node, expand the Web Sites node, and then expand the Default Web Site node.
  3. Right click on your virtual directory (WCFTestService) and select Properties.
  4. In the properties dialog box, click on Directory Security tab then click the Edit button** in the* Secure Communication* section.
  5. In the* Secure communications* dialog box, check the Require secure channel (SSL) checkbox.
  6. Click the Ok button in the Secure communications dialog box.
  7. Then click Ok button in the properties dialog box.

Step 6 – Configure wsHttpBinding for Username Authentication and TransportWithMessageCredential Security

In this step you will configure the WCF service to use Username authentication and Transport with Message security.

  1. In the Solution Explorer, right-click the Web.config file of the WCF service and choose the Edit WCF Configuration option.
  2. If you do not see the Edit WCF Configuration option, click the Tools menu and select WCF Service Configuration Editor. Close the WCF Service Configuration Editor tool that appears. The option should now appear on the web.config context menu.
  3. In the configuration editor, in the Configuration section, expand Service and then expand Endpoints.
  4. Select the first node Empty Name. Set the name attribute to wsHttpEndpoint.
  5. Click the Identity tab and delete the Dns attribute value.
  6. In the configuration editor, select the Bindings folder.
  7. In the Bindings section choose New Binding Configuration.
  8. In the Create a New Binding dialog box, select wsHttpBinding.
  9. Click Ok.
  10. Set the Name of the binding configuration to some logical and recognizable name, for example wsHttpEndpointBinding.
  11. Click the Security tab.
  12. Set the Mode attribute to TransportWithMessageCredential, from the drop down.
  13. Set the MessageClientCredentialType to UserName option from the drop down.
  14. Set the TransportClientCredentialType to None option from the drop down.
  15. Select the wsHttpEndpoint node in the configuration section.
  16. Set the BindingConfiguration attribute to wsHttpEndpointBinding from the drop down. This associates the binding configuration setting with the binding.
  17. In the configuration editor dialog, on the File menu, select Save.
  18. In Visual Studio, open your configuration and comment out the identity element. It should look as follows:
  <dns value="" />
  1. In Visual Studio, verify your configuration. The configuration should look as follows:
   <binding name="wsHttpEndpointBinding">
          <security mode="*TransportWithMessageCredential*">
            <*transport* clientCredentialType="*None*" />
            <*message* clientCredentialType="*UserName*" />
  <service behaviorConfiguration="ServiceBehavior" name="Service">
    <endpoint address="" binding="wsHttpBinding"
      *name="wsHttpEndpoint"* contract="IService">
**            <!--<identity>
        <dns value="" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

Step 7 – Configure the Service to Publish Metadata Securely

In this step, you configure your WCF Service to publish and secure the Metadata. By publishing the Metadata, you will allow your client to add a reference to your WCF Service.

  1. In the configuration editor, expand the Services node, and then expand Endpoints.
  2. Select the second end point created Empty Name and set the Name attribute to MexHttpsBindingEndpoint
  3. Set the Binding attribute to mexHttpsBinding from the drop down.
  4. On the configuration editor dialog, got to File menu and select Save.
  5. In Visual Studio, verify your configuration in Web.config. The configuration should look as follows.
      <service behaviorConfiguration="ServiceBehavior" name="Service">
    		<endpoint address="" binding="wsHttpBinding"
      		*name="wsHttpEndpoint"* contract="IService">
        <endpoint address="mex" *binding="mexHttpsBinding"* bindingConfiguration=""
            *name="MexHttpsBindingEndpoint"* contract="IMetadataExchange" />
  1. In the configuration editor, expand the Advanced node, and then expand the Service Behaviors and Service Behavior nodes.
  2. Select the serviceMetadata node.
  3. Set the HttpGetEnabled attribute to False and** the* HttpsGetEnabled* attribute to* True*.
  4. On the configuration editor dialog, got to File menu and select Save.
  5. In Visual Studio, verify your configuration in App.config. The configuration should look as follows.
      <behavior name="ServiceBehavior">
          <serviceMetadata *httpGetEnabled*="*false*" *httpsGetEnabled*="*true*" />
          <serviceDebug includeExceptionDetailInFaults="false" />
 In terms of the service and the client, some additional handling is necessary.
This entry was posted in Software Development. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s