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.
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.
<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:
<clientCertificate findValue="…" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySerialNumber" />
<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" />
<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!