none
WCF - validate different certificates (X509) RRS feed

  • Question

  • Hi there,

    I have a web.config with 3 different services/endpoints. 3 different clients will access the for them provided endpoint but should not use the other 2 endpoints. To validate the client's certificate I use a custom X509CertificateValidator. In the web.config:

    <authentication certificateValidationMode="Custom" customCertificateValidatorType="MyX509CertificateValidator, service" />

    and in c# like in the example: http://msdn.microsoft.com/de-de/library/system.identitymodel.selectors.x509certificatevalidator.aspx

    The problem is how can I differ the certificates in this MyX509CertificateValidator? I would prefer a generic class solution.

    Thanks,
    kind regards

    Wednesday, October 9, 2013 4:18 PM

Answers

  • Hi,

    Each client will have its own unique certificate attached, in order to validate each client, please try to check the following:
    //Client Code
    
    CustomerService.CustomerServiceClient client = new CustomerService.CustomerServiceClient();
    client.ClientCredentials.ClientCertificate.SetCertificate("cn=localhost", StoreLocation.LocalMachine, StoreName.My);
    <system.serviceModel>
     
        <services>
          <service behaviorConfiguration="myApp.ServiceBehavior" name="myApp.CustomerService">
            <endpoint address="" binding="basicHttpBinding" contract="myApp.ICustomerService"  bindingConfiguration="CustomBinding"/>
          </service>
        </services>
        
        <behaviors>
          <serviceBehaviors>
            <behavior name="myApp.ServiceBehavior">
              <serviceMetadata httpsGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <serviceCredentials>
                <clientCertificate>
                  <authentication certificateValidationMode="Custom" customCertificateValidatorType="myApp.Authentication.MyX509CertificateValidator, myApp" />
                </clientCertificate>
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <bindings>
          <basicHttpBinding>
            <binding
              name="CustomBinding" >
              <security mode="TransportWithMessageCredential">
                <message clientCredentialType="Certificate"/>
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
      
      </system.serviceModel>
        public class MyX509CertificateValidator : X509CertificateValidator
        {
            public MyX509CertificateValidator() : base() { }
    
          
            public override void Validate(X509Certificate2 certificate)
            {
                if (certificate == null)
                {
                    throw new SecurityTokenException(Properties.Resource.CertificateMissing);
                }
    
                if (!AuthenticationComponent.IsAuthenticatedUser(certificate.Thumbprint))
                {
                    throw new SecurityTokenException(Properties.Resource.InvalidCredentials);
                }
            }
    
        }

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, October 15, 2013 6:02 AM
    Moderator

All replies

  • Hi,

    The service exposes a single endpoint for communicating with the service, defined using the configuration file App.config. The endpoint consists of an address, a binding, and a contract. The binding is configured with a standard wsHttpBinding that defaults to using WSSecurity and client certificate authentication. The service behavior specifies the Custom mode for validating client X.509 certificates along with the type of the validator class. The behavior also specifies the server certificate using the serviceCertificate element. The server certificate has to contain the same value for the SubjectName as the findValue in the serviceCertificate element of serviceCredentials.

    <system.serviceModel>
        <services>
          <service name="Microsoft.ServiceModel.Samples.CalculatorService"
                   behaviorConfiguration="CalculatorServiceBehavior">
            <!-- use host/baseAddresses to configure base address -->
            <!-- provided by host -->
            <host>
              <baseAddresses>
                <add baseAddress =
                    "http://localhost:8001/servicemodelsamples/service" />
              </baseAddresses>
            </host>
            <!-- use base address specified above, provide one endpoint -->
            <endpoint address="certificate"
                   binding="wsHttpBinding"
                   bindingConfiguration="Binding" 
                   contract="Microsoft.ServiceModel.Samples.ICalculator" />
          </service>
        </services>
        <bindings>
          <wsHttpBinding>
            <!-- X509 certificate binding -->
            <binding name="Binding">
              <security mode="Message">
                <message clientCredentialType="Certificate" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceDebug includeExceptionDetailInFaults ="true"/>
              <serviceCredentials>
                <!--The serviceCredentials behavior allows one -->
                <!-- to specify authentication constraints on -->
                <!-- client certificates. -->
                <clientCertificate>
                  <!-- Setting the certificateValidationMode to -->
                  <!-- Custom means that if the custom -->
                  <!-- X509CertificateValidator does NOT throw -->
                  <!-- an exception, then the provided certificate -- >
                  <!-- will be trusted without performing any -->
                  <!-- validation beyond that performed by the custom-->
                  <!-- validator. The security implications of this -->
                  <!-- setting should be carefully considered before -->
                  <!-- using Custom in production code. -->
                  <authentication 
                     certificateValidationMode="Custom" 
                     customCertificateValidatorType =
    "Microsoft.ServiceModel.Samples.CustomX509CertificateValidator, service" />
                </clientCertificate>
                <!-- The serviceCredentials behavior allows one to -- >
                <!--define a service certificate. -->
                <!--A service certificate is used by a client to  -->
                <!--authenticate the service and provide message  -->
                <!--protection. This configuration references the  -->
                <!--"localhost" certificate installed during the setup  -->
                <!--instructions. -->
                <serviceCertificate findValue="localhost" 
                     storeLocation="LocalMachine" 
                     storeName="My" x509FindType="FindBySubjectName" />
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
          </system.serviceModel>
    

    Tuesday, October 15, 2013 5:43 AM
  • Hi,

    Each client will have its own unique certificate attached, in order to validate each client, please try to check the following:
    //Client Code
    
    CustomerService.CustomerServiceClient client = new CustomerService.CustomerServiceClient();
    client.ClientCredentials.ClientCertificate.SetCertificate("cn=localhost", StoreLocation.LocalMachine, StoreName.My);
    <system.serviceModel>
     
        <services>
          <service behaviorConfiguration="myApp.ServiceBehavior" name="myApp.CustomerService">
            <endpoint address="" binding="basicHttpBinding" contract="myApp.ICustomerService"  bindingConfiguration="CustomBinding"/>
          </service>
        </services>
        
        <behaviors>
          <serviceBehaviors>
            <behavior name="myApp.ServiceBehavior">
              <serviceMetadata httpsGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <serviceCredentials>
                <clientCertificate>
                  <authentication certificateValidationMode="Custom" customCertificateValidatorType="myApp.Authentication.MyX509CertificateValidator, myApp" />
                </clientCertificate>
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <bindings>
          <basicHttpBinding>
            <binding
              name="CustomBinding" >
              <security mode="TransportWithMessageCredential">
                <message clientCredentialType="Certificate"/>
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
      
      </system.serviceModel>
        public class MyX509CertificateValidator : X509CertificateValidator
        {
            public MyX509CertificateValidator() : base() { }
    
          
            public override void Validate(X509Certificate2 certificate)
            {
                if (certificate == null)
                {
                    throw new SecurityTokenException(Properties.Resource.CertificateMissing);
                }
    
                if (!AuthenticationComponent.IsAuthenticatedUser(certificate.Thumbprint))
                {
                    throw new SecurityTokenException(Properties.Resource.InvalidCredentials);
                }
            }
    
        }

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, October 15, 2013 6:02 AM
    Moderator