.netwcfcertificate

WCF Service that identifies client by certificate


we've got a WCF Service using BasicHttpBinding with server- and client-certificates. We are using Transport security:

<security mode="Transport">
  <transport clientCredentialType="Certificate" />
</security>

So far everything works (client calls a webmethod and is only allowed to, if the client certificate is issued by the trusted CA).

Now we want to check in the WCF service, if the client certificate is a specific certificate. The certificate we are looking for is known (installed on) the server, too.

How do we get the used client certificate in the service code? How do we load the certificate we want to compare to? How do we compare?


Solution

  • Haven't actually tried this myself but the technique shown in this MSDN article seems to be what you're looking for. It explains how to create a custom certificate validator, (didn't know this was possible).

    The original answer was a bad link only with a few words of fluff...

    Here is at least the gist of what is needed from the link above. The following should be a starting point that will be available if the link disappears:

    First, implement your custom certificate logic in a class inheriting from X509CertificateValidator

    WCF Service: Merge this XML to your existing configuration if using XML:

        <configuration>  
         <system.serviceModel>  
          <behaviors>  
           <serviceBehaviors>  
            <behavior name="ServiceBehavior">  
             <serviceCredentials>  
              <clientCertificate>  
              <authentication certificateValidationMode="Custom" customCertificateValidatorType="Samples.MyValidator, service" />  
              </clientCertificate>  
             </serviceCredentials>  
            </behavior>  
           </serviceBehaviors>  
          </behaviors>  
        </system.serviceModel>  
        </configuration>
    

    or in code:

      serviceHost.Credentials.ClientCertificate.Authentication
             .CertificateValidationMode = X509CertificateValidationMode.Custom;
      serviceHost.Credentials.ClientCertificate.Authentication
            .CustomCertificateValidator = 
                new MyX509CertificateValidator("CN=Contoso.com");
    

    WCF Client: Merge this XML to your existing configuration if using XML:

        <configuration>  
         <system.serviceModel>  
          <behaviors>  
           <endpointBehaviors>  
            <behavior name="clientBehavior">  
             <clientCredentials>  
              <serviceCertificate>  
               <authentication certificateValidationMode="Custom" customCertificateValidatorType= "Samples.CustomX509CertificateValidator, client"/>  
              </serviceCertificate>  
             </clientCredentials>  
            </behavior>  
           </endpointBehaviors>  
          </behaviors>  
         </system.serviceModel>  
        </configuration>  
    

    or in code:

        ClientCredentials creds = new ClientCredentials();
    
        creds.ServiceCertificate.Authentication.CertificateValidationMode = 
           X509CertificateValidationMode.Custom;
        creds.ServiceCertificate.Authentication.CustomCertificateValidator = 
           new MyCertificateValidator();