WCF – 2 Way SSL Security using Certificates

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:

    <binding name="CertificateWithTransport">
      <security mode="Transport">
        <transport clientCredentialType="Certificate" />

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,

       <behavior name="BindingBehavior">
                  <serviceMetadata httpsGetEnabled="true"/>
                  <serviceDebug includeExceptionDetailInFaults="true"/>


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,

      <service behaviorConfiguration="BindingBehavior"
        <endpoint binding="wsHttpBinding"         contract="SSPNotificationReceiver.IReceiverService" bindingConfiguration="CertificateWithTransport">
        <!–<endpoint address="mex" binding="mexHttpsBinding"
            name="MetadataBinding" contract="IMetadataExchange"/>–>

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.

  • Set Anonymous Access on IIS for your website (another important task which you might easily miss out) and remove all other authentication modes.


  • On the Directory Security tab, click Server Certificate and choose “Create new Certificate”. Follow the wizard to generate the certificate request. The certificate request is by default created in “c:\certreq.txt”
  • Open the Certtificate Services Website. It is generally http://localhost/certsrv on the server which is running the certificate authority.


  • Click on the Request a Certificate link


  • On the next screen, click on advanced certificate request


  • Choose the second option in the above screen


  • In the next screen, paste the contents of the c:\certreq.txt file in the saved request textbox as shown above.
  • After you click submit, the certificate is created and queued in the Pending Requests on the Certificate Authority.
  • Open Certificate Authority in the Windows Server 2003 machine


  • Issue the certificate.
  • Again, go back to the Certification Services and click on the “View Status of the pending requests” link in the home page.


  • Click on Download Certificate link and save the certificate to a location and name it SSLServerCert.cer


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.

  • On the Certificate Services home page, click on Request a Certificate option which will take you to the page shown below.


  • Click on advanced certificate request option in this page.
  • In the next page, click on “Create and submit a request to CA” option
  • Choose “Client Authentication Certificate” in the Type of certificate needed drop down.
  • Give all text boxes with appropriate information in the Identifying Information section.
  • Check “Mark Keys as exportable” option


  • Click Submit
  • As you did for SSL Server Certificate, go to Certification Authority and Issue this certificate as well
  • Come back to the Certificate Services again and click on Install Certificate link


  • Your Certificate will be installed in your Personal Store as shown below


  • You can export this cert with private key and send it across to the client who is going to use the certificate for authenticating itself.

Configuring IIS for 2 Way SSL Authentication

  • On your website’s directory security tab, click on Server Certificate
  • Click next and choose the option as shown below


  • Follow the wizard and select the SSLServerCert.cer that you already saved
  • Once finished, again click Edit button in the Secure Communications Section in Directory Security tab.


  • Check the Require secure channel (SSL) option
  • Choose Require client certificates under Client Certificates section

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

  • Check Enable client certificate mapping option
  • Click Edit to create a 1-1 certificate mapping
  • Browse to the client certificate that you already created and give map a local user account to it. All requests that carry this certificate will run using the account that you give here
  • Now, you have completed the entire hosting part of the service. The Service that you created is secured by SSL Server as well as SSL Client authentication.

Configuring the client to use SSL

          <binding name="WSHttpBinding_IReceiverService">
            <security mode="Transport">
              <transport clientCredentialType="Certificate" />
            <endpoint address=
https://YourIP/ReceiverHost.svc behaviorConfiguration="credentialConfiguration"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IReceiverService"
                contract="NotificationProxy.IReceiverService" name="WSHttpBinding_IReceiverService" />
          <behavior name="credentialConfiguration">
              <clientCertificate findValue="99bbc6c9e6f4a6bd526bc8bb21f9c21f0716c23r"
          x509FindType="FindByThumbprint" />


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:



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 !!

Comments (43)

  1. Prashant says:

    Hey I got nice help from blog.

    but I am still endup with Exception.

    "The SSL settings for the service ‘None’ does not match those of the IIS ‘Ssl, SslNegotiateCert, SslRequireCert, SslMapCert’"

    If i change trasport secutity from "trasport" to "trasportwithMessageCredential" It works. But again I end up with "Could not establish trust relationship for the SSL/TLS secure channel with authority"

    Can you tell me the cause.

  2. imayak says:

    For this error "Could not establish trust relationship for the SSL/TLS secure channel with authority", check that the SSL Certificate that you have is trusted on the client.

    That is, the SSL certificate issuer should be in the Trusted Store of your client computer. If your SSL certificate is issued from a Trusted CA like Verisign,you shouldn’t be facing this problem because all of the known Verisign issuers are already trusted.

    However, if you are testing with a temporary certificate which you created using makecert.exe or got from a test CA like Comodo, you will face this problem.

    If you still want more clarifications, let me know what kind of binding configuration you are using, so that I can help you out with the right settings.

    Good luck.

  3. Manpreet says:

    Excellent description. Keep up the good work.

  4. Anony Mouse says:

    Good blog. Thanks.

    I am a little confused about anonymous access too. Can you write a wcf service that just uses anonymous access without encryption and without windwos authentication?

    I know you would not want to do this, but want to know if you can.

    Otherwise is it safe to assume all wcf services must use certificate based authentication?

  5. imayak says:

    You can always set the WCF service to use no authentication at all. Of course no one would want to do that, but its possible.

    On your second question, it is not required for all WCF services to use certificate based authentication.

    WCF Services must be configured for SSL client certificate authentication only if the clients are already "known" to the service. (ie., Intranet applications or when you have a defined set of customers to access the service)

    Internet based non-critical services generally don’t use client certificates.

  6. John says:

    You can leave the mex endpoint uncommented if you configure it to use wsHttpBinding and the same bindingConfiguration as your service uses.  For example,

    <endpoint address="mex" binding="wsHttpsBinding"

     name="MetadataBinding" contract="IMetadataExchange" bindingConfiguration="CertificateWithTransport"/>

    For more info see:


    (Custom Secure Metadata Endpoint)

  7. Maxim says:

    Nice and useful article!

    But even after enabling anonymous in IIS and disabling mex, I still get errors:

    Service error: The HTTP request was forbidden with client authentication ‘Anonymous’. Service Fault: The remote server returned an error: (403) Forbidden.

    What could be the reason?

  8. Ashley Tate says:

    @Maxim: I ran into the same error and have documented at least one cause here:


  9. imayak says:

    @Maxim : It’s true that sometimes the error messages aren’t very clear and helpful in troubleshooting. Just go through the settings once again and ensure that everything is right.

  10. meir says:

    great article.

    but when i checked the Require SSL in iis (7.0).

    then every time i get Internal Server Error.


  11. meir says:

    i found out that if iis is configured as Require SSL, i had 2 comment the HTTP binding/endpoint swctions  in the web.config to get it to work.


  12. Chris Mullins says:

    I was able to get the MEX endpoint to work using this same approach. The issues is the binding and bindingConfiguration of the endpoint.

    Step 1 was to create a service behavior that required SSL.



           <behavior name="MyName">

             <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false"/>          




    Step 2 is to enable the MEX endpoint using the wsHttpBinding and proper binding configuration. In this case, the binding configuration is the same as the primary endpiong name.

    <endpoint address="mex" binding="wsHttpBinding" contract="IMetadataExchange" bindingConfiguration="MyBinding" />

    Doing this worked fine. To get to the MEX endpoint, a client cert is required – which is exactly what I wanted.

  13. imayak says:

    Meir >> I can’t get your problem. Can you post your bindings as well?

  14. Jaster says:

    Awsome Work!

    But i’m still expirencing some trouble. I can create an instance of the service, but i can’t call any methods. i recieve an errormessage like: "could not establish trusted ssl/tsl channel…"

    any ideas?



  15. imayak says:

    It’s basically a certificate trust issue. The client machine that you are using to talk to the server does not trust the certificate that you are using on your server.

    Make sure the certificate’s ‘CN’ property has the domain name.

    Eg., If the WCF Service URL is : https://myserver/services/service.svc

    then, your certificate should be issued to "myserver". i.e., you should see CN=myserver in the certificate properties.

    If this is also done, then install the certificate in the trusted store of the client machine. It should work.

  16. T.Chowdhury says:

    Very Good Article, follwoing your steps I was able to install my service using SSL. Although few of my steps somehow differ than what it has stated in the article. I will comeback to later on that.

    First I have few questions in code below (Configuring the client to use SSL) which certificate thumb print represents below Client or Server? My second question is how do I know what’s the value of


    <behavior name="credentialConfiguration"><clientCredentials><clientCertificate findValue="99bbc6c9e6f4a6bd526bc8bb21f9c21f0716c23r" storeLocation="CurrentUser" x509FindType="FindByThumbprint" />

  17. imayak says:


    In the behavior, you must give the client certificate’s thumbprint value.

    In the storeLocation attribute, give the name of the store where the certificate resides. There are multiple certificate stores on the computer and here is how you open them.

    On Run -> Type mmc and press Enter

    Press Ctrl +M

    On Add or Remove Snap-ins window, select Certificates and click Add button

    A new window with

    1. My User Account

    2. Service Account

    3. Computer Account


    If you select "My User Account", you will be able to see all certificates accessible to that particular windows user account.

    If you select Service Account, you will be able to see all certificates accessible to that particular windows service that you will eventually choose in the next window.

    Sample theory applies to the third option as well.

  18. Thank you for the great post. The only problem we have noticed that once Anonymous is enabled on IIS, ANY certificate issued by CA that is in trusted authorities store is granted access.

    Is there a possibility to restrict access to just one specific Cert?

  19. T.Chowdhury says:

    Hi, here are some good news and bad news. Good news is following your steps, I was able to install my service using SSL as well as consume the service from a client (console application). No issue.

    The app config file used for the client console application shown as below




                   <binding name="EmailServiceHttpsEndpoint">

                       <security mode="Transport">

                           <transport clientCredentialType="Certificate" />






               <endpoint address="https://tnsiit.tnsinsideit.local/EmailService/EmailService.svc&quot;

                   behaviorConfiguration="credentialConfiguration" binding="wsHttpBinding"

                   bindingConfiguration="EmailServiceHttpsEndpoint" contract="EmailClient.EmailService.IEmailService"

                   name="EmailServiceHttpsEndpoint" />




             <behavior name="credentialConfiguration">


                 <clientCertificate findValue="c72e3caa4ae63e20791f10bc6ab99ef24a2cc34d"   storeLocation="CurrentUser"  x509FindType="FindByThumbprint" />






    The bad news is after that I have created an ASP.net application, trying to consume the same service. I have cut & paste the above configuration into ASP.net web config, we I was testing the above service via aspx page, I’m getting this error

    Cannot find the X.509 certificate using the following search criteria: StoreName ‘My’, StoreLocation ‘CurrentUser’, FindType ‘FindByThumbprint’, FindValue ‘c72e3caa4ae63e20791f10bc6ab99ef24a2cc34d’.

    Do I have to do something different for ASP .NEt  application.

    Any help will be really appreciable.

  20. erosen03 says:

    Thanks for a great post. I had a similar issue trying to figure out why a particular WCF service kept reporting that it needed anonymous authentication enabled in IIS, even after I corrected the items in the WCF service’s web.config file. It turned out for me that even though web.config changes are supposed to be applied immediately after the file is saved, I had to issue an IISRESET command in order for the error message about anonymous access to go away.

  21. Sahil Malik says:

    Hi Imaya,

    This is a good article, and you being the original source, it has been shamelessly copied all over the internet by people claiming it as their own. Anyway, credit goes to you for the original.

    I wanted to point out a couple of things though.

    a) Setting anonymous is not necessary. You’ve had to set anonymous over there because your service settings are not properly translating the certificate identity into an identity that the service will understand, i.e. an AD identity for instance. Try doing the mapping using serviceBehavior/service-clientCredentials .. and you’ll see what I’m saying.

    b) Metadata exchange does not need to be turned off either. You simply need to do httpsEnabled – true, or enable metadata over HTTPS as one other comment mentioned above.

    Great post otherwise. Love it.


  22. imayak says:

    Thanks Sahil.

    I appreciate your clarification for the issues mentioned.

  23. Manav says:

    Hi Imaya,

    Thanks for the great post. I exactly had the same issues, and your article pulled me out. My only grievence is I found you article when I had struggled thru and fixed almost all the issues, and was stuck at the last one – related to commenting the mex endpoint.

    Still a great post. Keep up the good work.


  24. Alex says:

    Hi Imaya,thanks for your great post.

    By the way,what do you mean by terms of "2 way SSL security?"

    what is the typical usage scenario for it?

  25. imayak says:

    @Alex : It’s just that the client will also have a SSL certificate so the server can authenticate the client. So, I call it ‘2 Way’.

  26. Chloé says:

    hi imayak,

    thank you for taking your time and help us all. i have a problem =)

    before i found your post, i already figured out how to set up https on my dev machine running xp as well as my QA 2003 server with self certificate.

    my project (website) is a distribution website, therefore, i cannot use static url in the web.config or in the clientconfig. i find the Uri and create the proxy from there.

    everything works great! with two end points in the web.config file.

    1 – basicHttpBinding

    2 – wsHttpBinding

    hitting the wsdl with http or https works, however, when i set SSL Required on, i can’t get to the wsdl at all. if i remove basicHttpBinding section or wsHttpBinding and remove httpGetEnabled (basicHttpBinding) or httpsGetEnabled (wsHttpBinding) out of the serviceMetadata, then it works.

    Question 1) Any thought?

    Question 2) do i need those end points in the web.config? Can i do it dynamically when i about to call WCF?

    I’m new to WCF as well, so if you or anyone knows how to create a dynamic end point w/out any end point in the web.config, please feel free to give me info.

    thank you very much.


  27. Laleh Tajrobehkar says:

    Thanks alot for your blog. I have been trying ot get my WCF service with two way SSL work for a long time. Today finally I came across your blog and followed your detailed instructions. It worked. The part I was missing was commenting out the mex endpoint as well as anonymous access.

    Thanks again!


  28. Anand says:


    Am facing the similar issue.  i did as per the instruction here but still the issue is not resolved.

    Here is a list of steps i did

    1a. Created WCF service and exposed it in IIS on Windows 2003 OS

    1b. Created WCF test client and it is running in the same machine (Win 2003 OS)

    2. Created a server certificate and client certificate using Win 2003 certicate utility. Placed these in Local Machine & Local user in the following places TrustedPeeople/Personal/Trusted Root.

    3. Enabled the Security mode as TransportWithMessageCredentials. Authorization is done using certificate.

    4. Mapped the server certificate in IIS and enabled these settings in the WebSite which exposes WCF

         a. Enabled Require SSL Channel

         b. Require Client Certificate

         c. Enable client certificate mapping – used 1-1 mapping and mapped the client certificate to my login username/pwd.  

    5. used httpcfg utitlity to mapp the thumbpring hash to and with these switch -m 1 and -f 2

    6. I could able to view the .svc file and WSDL file in Internet Explorer. IE pops up a screen to choose my client certificate.. and on choosing wsdl is displayed without any problem.

    7. But the said exception comes when i call a contract using the test client which is also running in the same machine & with same login info.

    Please let me know where am i missing.

  29. Nick says:


          Very good article. Do you have steps to do similar thing in IIS7 on Windows 2008 server.

  30. Matt says:

    "The only problem we have noticed that once Anonymous is enabled on IIS, ANY certificate issued by CA that is in trusted authorities store is granted access. Is there a possibility to restrict access to just one specific Cert?"

    This is the issue we’re having as well. Any client cert passed to the service works. How do you lock the service down to a specific cert?

  31. Matt says:

    To answer my own question above, it turns out you cannot lock the service down to a specific cert using transport security. You must use message security, specify PeerTrust, and make sure the cert is in the Trusted People store on the server. Hope this helps someone else.

  32. valvestater65 says:

    Thanks, very very helpful information keep it up!

  33. Amit Kumar says:

    I have followed the same steps.i can acces service with the help of browser but not able to add reference of service in console application.When i  add reference it throws an error:    

    There was an error downloading 'https://localhost/TestSSLServer/Service.svc&#39;.

    Metadata contains a reference that cannot be resolved: 'https://localhost/TestSSLServer/Service.svc&#39;.

    An error occurred while receiving the HTTP response to https://localhost/TestSSLServer/Service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

    The underlying connection was closed: An unexpected error occurred on a receive.

    Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.

    An established connection was aborted by the software in your host machine

    If the service is defined in the current solution, try building the solution and adding the service reference again.

  34. vlad s says:

    The article is missing the point. "Certificate mapping" is there to restrict access to those who have the right cert (the one used in mapping). If anybody (with any valid cert) can access the site, your mapping is useless. If you only want 2 way authentication – you dont need cert mapping, just use "require cert" option + ssl. To make mapping work, you have to use a DISABLED account when configuring anonymous access in IIS.

  35. Host to Host 2 way Trust/Cert says:


    I am wonder if this is the setup I need for a 2 way trust?

    I am trying to setup a 2 way HOST-to-HOST SSL certification, or something of the like.

    It's not really the same old Server -> Client ssl cert setup?

    I have my SSL certs installed on the server and the hierarchy with the provider (verisign/GoDaddy) is working and have the intermediate certs also configured

    We wish to send to my vendor my certs for them to install and conversely have them send their certs to us to install on IIS and have a 2 way trust.  I have my vendors certs, what is the procedure for the install/config on my end in IIS?

    Thanks in advance, Steve.

  36. WhoCares says:

    Anybody know how to do this in IIS 7? Already wasted a week on certs. Tried everything imaginable. This is damn ridiculous.

  37. LiveToCode says:

    Thanks for the great post! I followed the steps, but I could not get a prompt to select certificate while accessing the service. It got directly accessed. What could be the reason? I want it to prompt for certificate, did I miss anything?

  38. NEWBIE_CODER says:

    Hi, I am geting this error; PLEASE HELP ME!."The SSL settings for the service 'SslRequireCert' does not match those of the IIS 'Ssl, SslNegotiateCert'

  39. Koder says:

    I got this "The private key is not present in the X.509 certificate", any idea why so? I have exported PVX for the certificate. Still gives me this exception on Client Side.

  40. Vivek Patel says:

    Hi, This is a great article.

    How can I only use SSL @ Server side? That means i want to host WCF Services under SSL Site but I am not expecting my clients to have the SSL certificate? What Do I have to change for that in my configuration?


  41. tedros says:

    how can i secure my WCF without using certificates simply using user name and password


  42. Sandy says:

    how to configure/implement at in code aspx application side