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.

6 Comments

  • @Niraj,

    Yes, or you can use a custom message interceptor as I showed here. http://weblogs.asp.net/cibrax/archive/2009/03/20/custom-basic-authentication-for-restful-services.aspx


  • 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 .

  • @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.

  • 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





    will communication be still encrypted ?

    Too many questons, sorry.
    Thanks in advance.

  • Could you give an example of the GetCertificate method?

  • 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


Comments have been disabled for this content.