Just when I thought I had seen all possible 403 Forbidden errors and could pinpoint the 403 issues without looking into traces, I found myself surprised by another 403 error. I was testing a WWSAPI client to WCF server interop scenario. Only this time the WCF server was hosted on IIS 7.0 on Windows Server 2008. The WWSAPI client using WS_SSL_TRANSPORT_SECURITY_BINDING with client certificate failed with WS_E_ENDPOINT_ACCESS_DENIED (0x803D0005). The WS_ERROR object contained these error strings (they also showed up in WWSAPI traces in a reverse order. The order below resembles the stack trace of a managed exception):

There was an error communicating with the endpoint at 'https://NWSDC/securityTest/SslAppWithClientCert/Service1.svc'.

The server returned HTTP status code '403 (0x193)' with text 'Forbidden'.

The server understood the request, but cannot fulfill it.

 

Since this was a typical HTTPS mutual authentication scenario (i.e. client certificate is required), my past experience only pointed to these cases:

1.       The client certificate is not specified.

2.       The client certificate does not have a private key.

3.       The SSL server certificate binding is not configured to negotiate client certificate.

4.       The client certificate is not trusted by the server.

 

I was sure that the client certificate with a private key was specified properly since I’d used it in other scenarios. Also, the IIS web application was configured properly to require client certificate as I just did it. So I figured it had to be a distrusted client certificate case. But after I checked the client certificate, its issuer and the server certificate store. it turned out not to be the case. Couldn’t think of anything else from my experience, I had to resort to traces.

 

First I enabled the WCF tracing and reran the client. Nothing was captured. The error must have been returned by IIS before secure channel was established. So I enabled IIS Failed Request Tracing and reran the client. There in the tracing XML file, I clearly saw this Warning:

ModuleName="IIS Web Core", Notification="BEGIN_REQUEST", HttpStatus="403", HttpReason="Forbidden", HttpSubStatus="13", ErrorCode="The revocation function was unable to check revocation because the revocation server was offline. (0x80092013)", ConfigExceptionInfo=""

 

I suddenly realized that the client certificate I used contained a CRL distribution point (CDP) extension with a file scheme CRL. That must be the problem! So I changed the client code to use a different certificate that did not have a CDP extension. Problem fixed!