The following steps will help you get started:
1) First, you need root administration to create your client and server certificates. You can either use an external authority provider (e.g. Verisign) or create something like Microsoft Certificate Server yourself.
To create a Root Authority certificate for development, you can use the "makecert" tool that comes with Visual Studio, for example.
makecert -n "CN=MyRootCA" -r -sv RootCA.pvk RootCA.cer
2) Then you need to request / generate your client and server certificates. Both types of certificates can be installed as certificates on the local computer, and both must be signed using the same root right. You can request client certificates from the Microsoft Certificate Server web interface, for example. http://mycertserver/certsrv .
To create a development client certificate for each machine, you can use makecert again. Please note that client certificates are signed with the Root Authority certificate of the development created in step 1.
makecert -pe -n "CN=MyCert" -ss my -sky exchange -sk MyCert -iv MyRootCA.pvk -ic MyRootCA.cer -sr localmachine MyCert.cer
This will install the certificate on the machine that runs this command into the Personal Certificates folder in the local computer's repository.
For the server to trust client certificates, you need to install the Root Authority certificate for development in the store of trusted root certificate authorities of the server (for this, use the mmc Certificates snap-in). Clients must also have a root certificate installed in the same way that they trust their own certificates.
3) Configure the WCF service to require client authentication with a certificate (for example, via web.config).
<services> <service name="TestService" behaviorConfiguration="wsHttpCertificateBehavior"> <endpoint name="TestEndPoint" address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="TestService.IMyContract"> <identity> <dns value=""/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> </service> </services> <bindings> <wsHttpBinding> <binding name="wsHttpEndpointBinding"> <security mode="Message"> <message clientCredentialType="Certificate"/> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <behavior name="wsHttpCertificateBehavior"> <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/> <serviceCredentials> <clientCertificate> <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/> </clientCertificate> <serverCertificate findValue="CN=MyCert"/> </serviceCredentials> </behavior> </behaviors>
4) Now configure the caller (for example, via app.config).
<client> <endpoint name="wsHttpBinding" address="https://localhost/TestService/TestService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding" behaviorConfiguration="wsHttpCertificateBehavior" contract="TestService.IMyContract"> <identity> <dns value="MyCert"/> </identity> </endpoint> </client> <bindings> <wsHttpBinding> <binding name="wsHttpBinding"> <security mode="Message"> <message clientCredentialType="Certificate"/> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="wsHttpCertificateBehavior"> <clientCredentials> <clientCertificate findValue="MyCert" storeLocation="LocalMachine"/> <serviceCertificate> <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" trustedStoreLocation="LocalMachine"/> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors>