locked
Authenticate a client via certificates over HTTPS RRS feed

  • Question

  • The forum is rejecting my full question, so I'm going to have to post in pieces. I've been struggling with the configuration for this blasted WCF service for the past week, and I'm slowing beginning to suspect that what I'm trying to do is just not possible, despite the documentation.

    Quite simply, I want to have a WCF service require a client certificate (which the server will have in its cert store), and then access that identity with System.ServiceModel.ServiceSecurityContext. Additionally, this needs to use transport security.
    Monday, December 6, 2010 4:51 PM

Answers

  • Hi Chris,

    I think you can first turn on the "includeexceptionDetailInFaults" setting in the service so that it can return detailed error info in case this is a server-side issue. 

    <serviceBehaviors>
    
     <behavior name="ServiceBehavior">
    
      <serviceMetadata httpGetEnabled="true"/>
    
      <serviceDebug includeExceptionDetailInFaults="true"/>
    
     </behavior>
    
    </serviceBehaviors>
    
    
    
    Also, the WCF service tracing is also help for troubleshooting unexpected exceptions occurred in WCF service or client

    #Configuring Tracing
    http://msdn.microsoft.com/en-us/library/ms733025.aspx

    In addition, a common issue occurs when we use .NET c lient  to access a HTTPS/SSL protected resource is that we will need to validate the server SSL certificate. If you haven't used it already, you can try registring a certificate validation callback handler in client as mentioned in the following reference:


    #Validating X509 Certificates for SSL over HTTP
    http://msdn.microsoft.com/en-us/library/bb408523(EXCHG.140).aspx

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Mog Liang Tuesday, December 14, 2010 2:43 AM
    Tuesday, December 7, 2010 11:00 AM

All replies

  • Here's my server config:

    <system.serviceModel>
        <services>
          <service behaviorConfiguration="requireCertificate" name="Server.CXPClient">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="wsHttpEndpoint" contract="PartnerComm.ContentXpert.Server.ICXPClient" />
            <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="mexEndpoint" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="https://localhost:8371/Design_Time_Addresses/Server/CXPClient/" />
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="requireCertificate">
              <serviceMetadata httpsGetEnabled="true" />
              <serviceCredentials>
                <serviceCertificate findValue="CyberdyneIndustries" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
                <clientCertificate>
                  <authentication certificateValidationMode="ChainTrust" trustedStoreLocation="LocalMachine" />
                </clientCertificate>
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <wsHttpBinding>
            <binding name="wsHttpEndpointBinding" maxBufferPoolSize="5242880" maxReceivedMessageSize="5242880">
              <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="1073741824" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <security mode="Transport">
                <transport clientCredentialType="Certificate" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
      </system.serviceModel>

    Monday, December 6, 2010 4:52 PM
  • Here's my client config:

    system.serviceModel>
        <bindings>
          <wsHttpBinding>
            <binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
              receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
              transactionFlow="false" hostNameComparisonMode="StrongWildcard"
              maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
              textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <reliableSession ordered="true" inactivityTimeout="00:10:00"
                enabled="false" />
              <security mode="Transport">
                <transport clientCredentialType="Certificate" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <client>
          <endpoint address="https://localhost:8371/Design_Time_Addresses/Server/CXPClient/"
            binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" behaviorConfiguration="ClientCertificateBehavior"
            contract="ContentXPertServer.ICXPClient" name="wsHttpEndpoint" />
        </client>
        <behaviors>
          <endpointBehaviors>
            <behavior name="ClientCertificateBehavior">
              <clientCredentials>
                <clientCertificate x509FindType="FindBySubjectName" findValue="CyberdyneIndustries" storeLocation="LocalMachine" storeName="TrustedPeople" />
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
      </system.serviceModel>
      
    The code all works perfectly when security mode='None' over http, but of course, there's no authentication, and nothing in System.ServiceModel.ServiceSecurityContext. I've tried dozens of variations on all of these elements, and it all ends up inevitably with the request throwing an exception "An existing connection was forcibly closed by the remote host".

    I'm using a self-signed cert "CyberdyneIndustries", whose CA cert I've added to the trusted CA store. The cert checks out when I view it. I've gone through the ____ of http namespace management, and solved those problems as well. It simply looks like WCF doesn't really support this...please tell me I'm wrong.

    TIA.
    Monday, December 6, 2010 4:52 PM
  • what error do you get?

    remember you need to configure the server cert on iis.


    http://webservices20.blogspot.com/
    WCF Security, Interoperability And Performance Blog
    Monday, December 6, 2010 8:25 PM
  • Hi Chris,

    I think you can first turn on the "includeexceptionDetailInFaults" setting in the service so that it can return detailed error info in case this is a server-side issue. 

    <serviceBehaviors>
    
     <behavior name="ServiceBehavior">
    
      <serviceMetadata httpGetEnabled="true"/>
    
      <serviceDebug includeExceptionDetailInFaults="true"/>
    
     </behavior>
    
    </serviceBehaviors>
    
    
    
    Also, the WCF service tracing is also help for troubleshooting unexpected exceptions occurred in WCF service or client

    #Configuring Tracing
    http://msdn.microsoft.com/en-us/library/ms733025.aspx

    In addition, a common issue occurs when we use .NET c lient  to access a HTTPS/SSL protected resource is that we will need to validate the server SSL certificate. If you haven't used it already, you can try registring a certificate validation callback handler in client as mentioned in the following reference:


    #Validating X509 Certificates for SSL over HTTP
    http://msdn.microsoft.com/en-us/library/bb408523(EXCHG.140).aspx

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Mog Liang Tuesday, December 14, 2010 2:43 AM
    Tuesday, December 7, 2010 11:00 AM