Mutual Certificate Authentication for WCF REST services

When Mutual Certificate Authentication is configured for REST services, both, the client and the service perform identity verification or authentication through X509 certificates.

The client authenticates the service during the initial SSL handshake, when the server sends the client a certificate to authenticate itself. More information about this process can be found here.

The service on the other hand, performs similar validations on the certificate attached by the client consumer to the request message.

Some specific configuration settings are required in WCF to use this authentication scenario with REST services. The service must be configured with transport security (SSL), “certificate” as client credential type.

<webHttpBinding>

  <binding name="mutual">

    <security mode="Transport">

      <transport clientCredentialType="Certificate"/>

    </security>   </binding>

</webHttpBinding>

For example, the complete configuration for a REST service that provides ATOM feeds would be the following,

<system.serviceModel>

  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

  <services>

    <service name="MutualAuthenticationRest.FeedService">

      <endpoint address="" contract="MutualAuthenticationRest.IFeedService" binding="webHttpBinding" bindingConfiguration="mutual" behaviorConfiguration="mutual"></endpoint>

     </service>

  </services>

  <bindings>

    <webHttpBinding>

      <binding name="mutual">

        <security mode="Transport">

          <transport clientCredentialType="Certificate"/>

         </security>

       </binding>

     </webHttpBinding>

    </bindings>

    <behaviors>

      <endpointBehaviors>

        <behavior name="mutual">

          <webHttp/>

        </behavior>

     </endpointBehaviors>

   </behaviors>

</system.serviceModel>

The virtual directory used for hosting the service in IIS must also be configured with the same security settings.

MutualCertificate

The client application only need to attach the certificate at the moment of consuming the service. This can be easily done with the new HttpClient class shipped as part of the WCF REST Starter kit,

class Program

{

    static void Main(string[] args)

    {

        X509Certificate2 certificate = CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=clientCert");

        HttpClient client = new HttpClient();

        client.TransportSettings.ClientCertificates.Add(certificate); //Cert attached to the request

        string content = client.Get("https://localhost/MutualAuthentication/Service.svc?numItems=10").Content.ReadAsString();

        Console.WriteLine(content);

    }

}

CertificateUtil is an helper class that looks for an specific X509 certificate in the windows certificate store. In addition, if you are using test certificates, you might want to disable the service authentication on the client side, that can be done with a callback attached to the static class “ServicePointManager”.

For instance,

public class PermissiveCertificatePolicy

{

    public static void Enable()

    {

        ServicePointManager.ServerCertificateValidationCallback +=

           new RemoteCertificateValidationCallback(RemoteCertValidate);

    }

    static bool RemoteCertValidate(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)

    {

        return true;

    }

}

The method PermissiveCertificatePolicy.Enable should be called before consuming the service.

Comments

# Mutual Certificate Authentication for WCF REST services - Pablo M. Cibraro (aka Cibrax)

Friday, April 17, 2009 10:05 AM by DotNetShoutout

Thank you for submitting this cool story - Trackback from DotNetShoutout

# re: Mutual Certificate Authentication for WCF REST services

Thursday, May 07, 2009 12:40 AM by Niraj

Hi Pablo,

   Just wanted to confirm if I require just basic authentication over HTTPS for REST, do I still require a web.config & tweak Security mode to transport?

# re: Mutual Certificate Authentication for WCF REST services

Thursday, May 07, 2009 10:10 AM by cibrax

@Niraj,

Yes, or you can use a custom message interceptor as I showed here. weblogs.asp.net/.../custom-basic-authentication-for-restful-services.aspx

# re: Mutual Certificate Authentication for WCF REST services

Wednesday, May 27, 2009 8:20 AM by habibs

Hi Pablo,

what kind of certificate would you suggest ? I mean do we need to buy one from VeriSign or Thawte etc. or  using self generated certificate will do ?

How clients should obtain public key of server ? Should we send it via email or what ?

Thanks .

# re: Mutual Certificate Authentication for WCF REST services

Wednesday, May 27, 2009 8:42 AM by cibrax

@habibs,

It depends on how much money you want to spend :), all the certificates from a well-know authority work the same. Generally, if you use a self-signed certificate, your clients applications will start receiving warning about a non-trusted authority.

The clients will obtain the public key automatically during the ssl handshake, there is not need to download it manually.

Regards,

Pablo.

# re: Mutual Certificate Authentication for WCF REST services

Wednesday, May 27, 2009 9:24 AM by Alex

Hi Pablo, you wrote

"The service on the other hand, performs similar validations on the certificate attached by the client consumer to the request message."

Where does the client gets his certificate ? Should it be issued by the same CA that generated certificate for the service ?

If i will use

<security mode="Transport">

     <transport clientCredentialType="UserName"/>

</security>

will communication be still encrypted ?

Too many questons, sorry.

Thanks in advance.

# re: Mutual Certificate Authentication for WCF REST services

Monday, June 08, 2009 9:43 AM by Isaac

Could you give an example of the GetCertificate method?

# re: Mutual Certificate Authentication for WCF REST services

Wednesday, April 20, 2011 4:00 PM by Mike Bria

Isaac,

Here's my implementation:

public static class CertificateUtil

   {

       public static X509Certificate2 GetCertificate(StoreName storeName, StoreLocation storeLocation, string certSubject)

       {

           var store = new X509Store(storeName, storeLocation);

           store.Open(OpenFlags.ReadOnly);

           try

           {

               var certificates = store.Certificates;

               var results = certificates.Find(

                   X509FindType.FindBySubjectDistinguishedName,

                   certSubject, false);

               if (results.Count == 0)

                   throw new Exception("Unable to find certificate");

               else

                   return results[0];

           }

           finally

           {

               store.Close();

           }

       }

   }

# re: Mutual Certificate Authentication for WCF REST services

Wednesday, April 20, 2011 4:07 PM by Mike Bria

Hi Pablo,

I'm following your example, basically to the T, but still receiving a "HTTP 403.7 - Forbidden: Client certificate required" for the response.

Any ideas?  Any other info I can specify to help you help me?

Thanks, I'm under a real pinch here.

--Mike

Leave a Comment

(required) 
(required) 
(optional)
(required)