Accessing a BizTalk WCF Service over SSL with Client Certificate Authentication

Accessing a WCF Service published by BizTalk over SSL with client certificate authentication proved to be difficult. Here are some of the steps I had to do:

1. Publish the web service using the BizTalk WCF Service Publishing Wizard.

2. Add a service reference in the test client.

3. Change the receive location security mode to Transport and Transport client credential type to Certificate.

image

4. Generate a server certificate for IIS. Using IIS 7 Manager, I generated a self-signed certificate by selecting the server (top node), opening Server Certificates and then clicking on “Create a Self-Signed Certificate…”.

5. Create an https binding. (Select the web site and click on Bindings… on the right.)

6. Create a self-signed client certificate for testing. I used the following commands:

makecert -r -pe -n "CN=Henrik" -b 01/01/2007 -e 01/01/2010 -sky exchange Client.cer -sv Client.pvk
pvk2pfx.exe -pvk Client.pvk -spc Client.cer -pfx Client.pfx

7. Add Client.pfx to the Current User/Personal store and Client.cer to the Local Computer/Trusted People and Trusted Root Certificate Authorities store.

8. Select the application, double click SSL Settings. I used the following settings: Require SSL, require client certificates.

9. Obviously, the endpoint address in the client’s App.config must be changed from http://… to https://. But it must also be changed to use client certificates:

<bindings>
  <wsHttpBinding>
    <binding …
        <security mode="Transport">
          <transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
          …

10. To choose authentication certificate, you can either add the following code:

myClient.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySerialNumber, …)

or use the following configuration:

<behaviors>
  <endpointBehaviors>
    <behavior name="ClientCertificateBehavior">
      <clientCredentials>
        <clientCertificate findValue="…" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySerialNumber" />
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>
<client>
  <endpoint … behaviorConfiguration="ClientCertificateBehavior" />
  …

11. When I ran the test client, I got an exception. Looking in the application event log, I had the following error: “…Could not find a base address that matches scheme http for the endpoint with binding MetadataExchangeHttpBinding. Registered base address schemes are [https]…”

12. To resolve this, I had to modify the service Web.config. First I commented out
<endpoint name="HttpMexEndpoint" address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
and uncommented
<endpoint name="HttpsMexEndpoint" address="mex" binding="mexHttpsBinding" bindingConfiguration="" contract="IMetadataExchange" />
It didn’t work. Now, I got “…The SSL settings for the service ‘None’ does not match those of the IIS ‘Ssl, SslNegotiateCert, SslRequireCert’…” After a great deal of binging, I found that the solution was to comment out both these endpoints. Not so obvious!

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s