Introduction and goal

When we talk about WCF security, there are two ways: transport level security and message level security. Transport level security is nothing but
built-in security by protocols. In message level security, we need to encrypt data, in other words security is injected in the data itself.
In this article, we will look into how we can implement transport level security using WsHttp bindings. We do not need to do extra development for transport
level security because it’s more of a protocol inherent security model. In this article we will implement WsHttp using HTTPS as transport security.

Step 1: Create a simple service using a WCF project

The first step is to create a simple WCF project. So click on New Project and select WCF Service Project. By default, a WCF project creates a default function GetData().
We will be using the same function for this sample.

Step 3: Tie up the binding and specify the HTTPS configuration

We need to now tie up the bindings with the end points. So use the bindingConfiguration tag to specify the binding name. We also need to specify the address
where the service is hosted. Please note the HTTS in the address tag.

Step 4: Make the web application HTTPS enabled

Now that we are done with the WCF service project creation and the necessary configuration changes, it’s time to compile the WCF service project
and host it in an IIS application with HTTPS enabled.

We will be using makecert.exe which is a free tool by Microsoft to enable HTTPS for testing purposes. MakeCert (Makecert.exe) is a command-line tool that
creates an X.509 certificate that is signed by a system test root key or by another specified key. The certificate binds a certificate name to the public part
of the key pair. The certificate is saved to a file, a system certificate store, or both.

You can get the same from C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin or you can also get it from the Windows SDK.

You can type the below at your DOS prompt on “C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin”. Please note “compaq-jzp37md0” is the server name
so you need to replace it with your PC name.

If you run this through your command prompt, you should get a succeeded message as shown below:

Now it’s time to assign this certificate to your IIS website. So go to IIS properties, click on the Directory Security tab, and you should see the Server Certificate button.

Click on the Server Certificate button and you will then be walked through the IIS Certificate Wizard. Click ‘Assign an existing certificate’ from the wizard.

You can see a list of certificates. The “compaq-jzp37md0” certificate is the one which we just created using ‘makecert.exe’.

Now try to test the site without ‘HTTPS’ and you will get an error as shown below… That means your certificate is working.

Do not forget to enable IIS anonymous access.

Step 5: Consume the service in a web application

It’s time to consume the service application in ASP.NET web. So click on Add Service Reference and specify your service URL. You will see a warning box as
shown in the below figure. When we used makecert.exe, we did not specify the host name as the service URL. So just let it go.

Step 6: Suppress the HTTPS errors

‘makecert.exe’ creates test certificates. In other words, it’s not signed by CA. So we need to suppress those errors in our ASP.NET client consumer.
We have created a function called IgnoreCertificateErrorHandler which returns true even if there are errors. This function is attached as a callback
to ServicePointManager.ServerCertificateValidationCallback.

In the same code, you can also see the service consuming code which calls the GetData function.

Comments and Discussions

This is a great article, nicely written, with clear source code and screenshots.
Really nicely done.

If, after following these instructions, my WCF service had actually worked under https, you'd be getting 5-stars and be my hero.

Unfortunately, it doesn't work, and if I look at the source code you've posted, well, it seems to completely ignore your own advice, and I ended up even more baffled as to what I was supposed to do.

(Out of interest, I created a brand new "Web Api" web service (rather than WCF) in Visual Studio, and that just worked straightaway under https. No messing around or spending hours desperately changing web.config without success.)

It doesn't seem to work if you do not ignore certificate errors... Or do we need some sophisticated logic in Certificate Error Handler? Of course, we can't just suppress all certificate errors in production code as somebody has already noted!

I have to access a REST service on a distant server. It works fine in a test console app. If I try to do the same when hosting it in a WCF service I get and error 405.
Any suggestions as to where to start looking.