I have built a WCF helloworld client and server. I want to use certificate authentication between them.
The error I get is "The caller was not authenticated by the service."
I have created two certificates using makecert.exe. The certificate on the client is installed under 'Personal' and 'Trusted People' and 'Third-Party Root Certification Authorities'. I copied the certificate as I don't know if it should be only under one heading
My server webconfig is as below
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="false" targetFramework="4.5.1"/>
<httpRuntime targetFramework="4.5.1"/>
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="BusinessToBusiness" name="TestHelloWork.Service1">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="BindingConfig" contract="TestHelloWork.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://win-gat-web01:7777/Service1"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="BindingConfig">
<security>
<message clientCredentialType = "Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="BusinessToBusiness">
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode = "PeerTrust"/>
</clientCertificate>
<serviceCertificate findValue="WCfServer"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
</configuration>
The client side web.config is as below
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://myserver:7777/Service.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1" behaviorConfiguration="CustomBehavior">
<identity>
<dns value="WCfServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="WcfClient" x509FindType="FindBySubjectName"
storeLocation="CurrentUser" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The client side certificate is installed under 'Personal'
Any idea what could be wrong? I have googled and realised that they should be on same domain? But they are. Also how will the domain work when my service is external?
Try to enable CAPI2 log. It is special log (not enabled by default) that contains certificate validation information. If your problem lies is in certificate validation procedure failing you will find useful info there. Look for errors. In my case it was something like
In my case I've had
But you are using
PeerTrustcertificate validation mode so according to this comment from WCF demos I haveI would assume that certificates should be placed like this:
Verify that you have granted rights on server private key to AppPool that your IIS WCF service runs under (default pool is
IIS APPPOOL\DefaultAppPool) It can be done usingmmcorcertlm.mscby right clilcking on server certificate thenAll Tasks->Manage Private Keys .... Verify that you do NOT have selected AD because IIS APPPOOL is a local group. Add accountIIS APPPOOL\your_pool_nameand hit OK.That will work if you have default settings in your AppPool like
Identityis set toAplicationPoolIdentityand not a custom account (it is common to use managed service account from AD) andLoad User Profileis set totrue.