Monday, April 27, 2009

Confusing Errors Using WCF Transport Security With Client Certificates

While prototyping a WCF service last week I ran into a number of confusing security-related errors on both the client and server. My setup was as follows:

  • Windows 2008 Server
  • IIS 7
  • .NET 3.5
  • basicHttpBinding/transport security/client certificates

Most of the errors that can result from this setup have been documented elsewhere. This detailed post by Imaya Kumar does a great job of walking through the overall configuration and explaining the error messages caused by various misconfigurations. However, I did run into one client error that wasn't specifically documented anywhere else:

System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.

This error actually indicates that your client certificate could not be validated by the server. In my case I was using self-generated client and root certificates, and I had inadvertently uninstalled the root certificate from my server.

A related gotcha is that setting a particular clientCertificate.certificateValidationMode for your service is meaningless when using transport security. For example, the "PeerTrust" value in the configuration snippet below is ignored. Client certificates seem always to be validated using the PeerOrChainTrust method when using transport security with the http bindings.

   1: <behaviors>
   2:   <serviceBehaviors>
   3:     <behavior name="TransportBehavior">
   4:       <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="false" httpsHelpPageEnabled="true" />
   5:       <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
   6:       <serviceCredentials>
   7:         <clientCertificate>
   8:           <authentication certificateValidationMode="PeerTrust" />
   9:         </clientCertificate>
  10:       </serviceCredentials>
  11:     </behavior>        
  12:   </serviceBehaviors>
  13: </behaviors>

4 comments:

partha said...

Hi,
Am facing a similar issue. Did u get the solution.

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 0.0.0.0 and 0.0.0.0:443 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.

partha said...

Please let me know how you resolved this issue

Ashley Tate said...

@partha: It could be a variety of things--tough to say without seeing your code and configuration. Since WCF is a Microsoft product, why don't you post your question to one of Microsoft's WCF forums: http://social.msdn.microsoft.com/Forums/en/wcf/threads

partha said...

Hi Ashely Tate,

Thanks for your suggestion. I have emailed you my web.config and client.config file (i could not able to post those file here). Please let me know how to resolve this.

Regards,
Anand

 
Header photo courtesy of: http://www.flickr.com/photos/tmartin/ / CC BY-NC 2.0