Thursday, May 19, 2016

The caller was not authenticated by the service. WCF with Certificate Credential

After setting all section in the config file everything works, but when I tried to call service from client then I got error "The caller was not authenticated by the service.

Cause

The problem was Client and Server Certificates (WcfServer & WcfClient) was on

In MMC
Console Root à Certificate Current User à Personal à Certificates
But NOT in
Console Root à Certificate Current User à Trusted People à Certificates

Solution
  • In MMC
  • Copy both certificates 
  • From: Console Root à Certificate Current User à Personal à Certificates
  • TO:    Console Root à Certificate Current User à Trusted People à Certificates

After done this it’s solve my problem.

How to set Security (Certificate) in WCF service, 9 simple steps are here

Create certificate by using makecert.exe
  • makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=WcfServer -sky exchange -pe
  • makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=WcfClient -sky exchange -pe

Mostly we have to set following sections in Server and Client Config files
  • services
  • behaviors
  • bindings
  • endpointBehaviors

 WCF Server Config
<services>
  <service name="WcfService1.Service1" behaviorConfiguration="wsHttpServices">
          <endpoint address=""
                    binding="wsHttpBinding"
                    bindingConfiguration="wsHttpBinding_config"
                    contract="WcfService1.IService1">
          </endpoint>
        </service>
</services>

<behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpServices">
>
  <clientCertificate>
         <authentication certificateValidationMode="PeerTrust"/>
  </clientCertificate>
        <serviceCertificate
findValue="WcfServer"
storeLocation="CurrentUser"
storeName="My" 
x509FindType="FindBySubjectName" >
</serviceCertificate>
 </serviceCredentials>
      </behavior>
   </serviceBehaviors>
</behaviors>

<bindings>
      <wsHttpBinding>
        <binding name="wsHttpBinding_config">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
</bindings>

WCF Client Config
<client>
      <endpoint address="http://localhost:65514/Service1.svc"
              binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="ServiceReference1.IService1" behaviorConfiguration="CustomBehavior"
              name="WSHttpBinding_IService1">
        <identity>
<dns value="WcfServer"/>         
        </identity>
      </endpoint>
</client>

<endpointBehaviors>
        <behavior name="CustomBehavior">
          <clientCredentials>
            <clientCertificate
findValue="WcfClient" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My"/>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
</endpointBehaviors>

<bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService1">
          <security>
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
 </bindings>

1 comment:

Cesar said...

could you explain why do we need to copy the certificate onto the Trusted People section?