John
John

Reputation: 11

WCF showing 403 Forbidden using SSL and client certificates

We are having a problem with WCF - we are getting the error below when trying to connect. There are tons of suggestions for various configurations, having tried them all we could use some help.

We are using HTTPS for transport security, using a real SSL certificate that we got from GoDaddy. It seems to be installed and working properly when we browse to web pages on the site. With no authentication, we can connect properly to our WCF service.

For authentication, we are using client certificates that we created ourselves. These client certificates were working fine before we switched to HTTPS, when we were using message security with a self-signed server certificate (which was a pain because we had to get the clients to install the server certificate).

Error The HTTP request was forbidden with client authentication scheme 'Anonymous'. Inner exception: The remote server returned an error: (403) Forbidden

Server configuration file

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="NewBinding0">
        <security mode="Transport">
          <transport clientCredentialType="Certificate" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <services>
    <service name="WcfService1.Service1">
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0" contract="WcfService1.IService1" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
          <clientCertificate>
            <authentication certificateValidationMode="PeerTrust" />
          </clientCertificate>
          <serviceCertificate findValue="....." x509FindType="FindByThumbprint" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <protocolMapping>
    <add scheme="https" binding="wsHttpBinding" bindingConfiguration="NewBinding0" />
  </protocolMapping>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

Client configuration file

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="NewBehavior0">
                <clientCredentials>
                    <clientCertificate findValue="customuser1"
                        storeName="TrustedPeople" x509FindType="FindBySubjectName" />
                </clientCredentials>
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <bindings>
        <wsHttpBinding>
            <binding name="NewBinding0">
                <security mode="Transport">
                    <transport clientCredentialType="Certificate" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://www.insertoursitename.com/WcfService1/Service1.svc"
            behaviorConfiguration="NewBehavior0" binding="wsHttpBinding"
            bindingConfiguration="NewBinding0" contract="ServiceReference1.IService1"
            name="wsHttpBinding_IService1" />
    </client>
</system.serviceModel>

Upvotes: 1

Views: 5284

Answers (1)

joedotnot
joedotnot

Reputation: 5153

My problem was very similar to yours, and i'll describe my scenario before answering the question.

  1. Created a simple WCF service (using custom binding, but that's irrelevant).
  2. Created a self-signed RootCA using makecert, and generated two certs tempCertServer.cer used for SSL encryption, configure IIS to require https, etc. --> Tested this part, worked ok from the Browser from a different computer.
  3. The second cert tempCertClient.cer was used as a client-cert to be presented to IIS, configure IIS to Require client-cert, etc. --> Tested this part from a browser (best to use IE since you can easily clear SSL state). I get a prompt to choose a client cert, but never connects, the error is exactly the same as per the question: "The HTTP request was forbidden with client authentication scheme 'Anonymous'. Inner exception: The remote server returned an error: (403) Forbidden."
  4. Replaced tempCertClient with a proper cert (from a known CA), there was no issue, connection was established and WCF page shown; No matter what i tried with the self-signed client cert, always getting above error.

Wasted a whole day++ trying various settings, reading blogs on registry changes, placing the cert server-side under different cert stores, changing config file settings, etc, with no resolution.

The answer was very simple, inspect the LocalComputer\Trusted Root Certification Authorities server-side, and remove any NON-ROOT CA's (i.e. those that should not be there, IssuedTo NOT EQUALS IssuedBy)

The client-cert itself did not need to be installed on the server, only a Root CA that can validate it has to be installed in LocalComputer\Trusted Root Certification Authorities server-side.

Upvotes: 3

Related Questions