I have WCF service. I demand clients to authenticate with certificate. This is service configuration:
<system.serviceModel>
<services>
<service name="FilmLibrary.FilmManager" behaviorConfiguration="FilmService.Service1Behavior">
<endpoint address="manager" name="certBinding" binding="basicHttpBinding" contract="FilmContract.IFilmManager" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="certBinding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="FilmService.Service1Behavior">
<serviceCredentials>
<clientCertificate>
<authentication trustedStoreLocation="LocalMachine"
certificateValidationMode="PeerTrust" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Public key is installed in LocalMachine, Trusted People
Client configuration is as follows:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="certBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="certBehaviour">
<clientCredentials>
<clientCertificate findValue="SubjectKey" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="[...]/Service1.svc/manager"
binding="basicHttpBinding" bindingConfiguration="certBinding" behaviorConfiguration="certBehaviour"
contract="FilmsService.IFilmManager" name="certBinding" />
</client>
</system.serviceModel>
Private key is installed in Personal, current user.
Without security, service works. With security enabled - it does not. I tried several configurations and I got errors like authentication failed or that I have to set service certificate in clientCredentials element. Which I don't understand because I do not want to authenticate service at all.
I found the following guide extremely helpful and very detailed. https://notgartner.wordpress.com/2007/09/06/using-certificate-based-authentication-and-protection-with-windows-communication-foundation-wcf/
It covers creating the service, the client, the certificates and adjusting the 2 configs.
Server:
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<!--only accept certificates in "Trusted People"-->
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Client:
<bindings>
<basicHttpBinding>
<binding name="customBinding1">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="customBehavior1">
<clientCredentials>
<!--fabrkam-->
<clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="d2 31 6a 73 1b 59 68 3e 74 41 09 27 8c 80 e2 61 45 03 b1 7e"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
We auto-redirect any HTTP requests to HTTPS so we have to use TransportWithMessageCredential type security. For normal Http using just Message as security type should also work.
Instead of
<serviceCredentials>
<clientCertificate>
<authentication trustedStoreLocation="LocalMachine"
certificateValidationMode="PeerTrust" />
</clientCertificate>
</serviceCredentials>
I think you are supposed to have
<serviceCredentials>
<serviceCertificate findValue="SubjectKey" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
</serviceCredentials>
You are not authenticating the service by this, instead you are telling the service how the client is to be authenticated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With