none
WCF Service to WSE Client - Certificate authentication over SSL RRS feed

  • Question

  • I am trying to access a WCF service with a WSE 3.0 client over SSL using certificate authentication.  I can do it over an unsecured channel using a customBinding on the service side using the MutualCertificate authentication mode and the turnkey policy assertion mutualCertificate11Security on the client side.  This breaks when I move it to a production environment accessible only by SSL and either (1) change nothing in the server config file--connection gets refused because it is not https--or by (2) changing the server custom binding to CertificateOverTransport--client errors with this:  System.InvalidOperationException: Security requirements are not satisfied because the security header is not present in the incoming message.

    My question is simply, how do I access a WCF service over SSL using certificate authentication?

    Thanks,
    Chris


    Friday, December 14, 2007 11:11 PM

All replies

  • Do you have anything similar to the scenarios in this post? http://blogs.msdn.com/wenlong/archive/2006/12/01/impersonation-with-double-identities.aspx

     

     

    If so, please follow Wenlong's advice to get things working.

    Sunday, December 16, 2007 2:12 PM
  • I'm not trying to do impersonation, just trying to authenticate using certificates over an SSL channel from WCF service to WSE 3.0 client.
    Monday, December 17, 2007 5:40 PM
  • Your options are requiring the client certificate with https integrated auth or some form of CertificateOverTransport.  I'm not familiar with WSE to WCF interop with CertOverTransport but if you send me a repro I can take a look (email or post to this thread).

     

    (Marked as answered due to lack of response.)

    Monday, December 31, 2007 5:38 PM
  • We do not have the option of using integrated authorization--I assume you mean against an LDAP server or the like.  We would like to do some type of CertificateOverTransport.  We're using the TransportWithMessageCredential security mode in the binding for our WCF clients, so what I want is an equivalent setup for our WSE clients.  I'm not sure what you mean by repro, but maybe you're looking for code.  I'm including the relevent parts of our config files, web and app.  Some names were changed to protect the innocent.

    The serviceModel node from our web config
        <system.serviceModel>
            <bindings>
          <customBinding>
            <!-- WSE X509 Certificate binding -->
            <binding name="wseCertificateBinding">
              <security authenticationMode="MutualCertificate"  messageProtectionOrder="SignBeforeEncrypt"
                        messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                        requireDerivedKeys="false" />
              <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
              <httpTransport/>
            </binding>
          </customBinding>
                <wsHttpBinding>
            <!-- WCF X509 Certificate binding -->
            <binding name="certificateBinding">
              <security mode="TransportWithMessageCredential">
                <message clientCredentialType="Certificate"/>
              </security>
            </binding>
                    <binding name="WSHttpBinding_Mtom" messageEncoding="Mtom" maxReceivedMessageSize="1000000"  />
                </wsHttpBinding>
            </bindings>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="Namespace1.WebServices.Reports.EmailBehavior">
              <serviceMetadata httpsGetEnabled="true" />
              <serviceCredentials>
                            <serviceCertificate findValue="f758ce5c8969a3c3f328e0fe934696545fe63d8a" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
                            <clientCertificate>
                                <authentication certificateValidationMode="Custom" customCertificateValidatorType="Namespace1.WebServices.Reports.CustomX509CertificateValidator, Namespace1.WebServices"/>
                            </clientCertificate>
                        </serviceCredentials>
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <services>
                <service behaviorConfiguration="Namespace1.WebServices.Reports.EmailBehavior"
                 name="Namespace1.WebServices.Reports.Email">
            <endpoint address="wseCertificateEndpoint"
                      binding="customBinding"
                      bindingConfiguration="wseCertificateBinding"
                      contract="Namespace1.WebServices.Reports.IEmail" >
            </endpoint>
                    <endpoint address="wcfCertificateEndpoint" binding="wsHttpBinding"
                      bindingConfiguration="certificateBinding" contract="Namespace1.WebServices.Reports.IEmail">
              <identity>
                <certificateReference findValue="f758ce5c8969a3c3f328e0fe934696545fe63d8a" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
              </identity>
                    </endpoint>
                    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                </service>
            </services>
        </system.serviceModel>

    The serviceModel node from our WCF client that works:
        <system.serviceModel>
            <bindings>
                <wsHttpBinding>
                    <binding name="WSHttpBinding_IEmail" 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="TransportWithMessageCredential">
                            <transport clientCredentialType="None" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Certificate" negotiateServiceCredential="true"
                                algorithmSuite="Default" establishSecurityContext="true" />
                        </security>
                    </binding>
                </wsHttpBinding>
            </bindings>
            <client>
                <endpoint address="https://ws.example.com/Reports/Email.svc"
                    behaviorConfiguration="ServicesBehavior" binding="wsHttpBinding"
                    bindingConfiguration="WSHttpBinding_IEmail" contract="EmailReportService.IEmail"
                    name="WSHttpBinding_IEmail" />
            </client>
          <behaviors>
            <endpointBehaviors>
              <behavior name="ServicesBehavior">
                <clientCredentials>
                  <serviceCertificate>
                    <authentication certificateValidationMode="PeerOrChainTrust" />
                  </serviceCertificate>
                  <clientCertificate findValue="Chris Petty" storeLocation="CurrentUser" storeName="My"
                                          x509FindType="FindBySubjectName"/>
                </clientCredentials>
              </behavior>
            </endpointBehaviors>
          </behaviors>
        </system.serviceModel>

    The configuration node from our WSE client app that works in development:
    <configuration>
      <configSections>
        <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
          <section name="ServicesTestClient_WSE.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
          <section name="WSSecurityCertificatePolicyClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </sectionGroup>
      </configSections>
      <microsoft.web.services3>
        <policy fileName="wse3policyCache.config" />
        <diagnostics>
          <trace enabled="false" input="InputTrace.webinfo" output="OutputTrace.webinfo" />
        </diagnostics>
      </microsoft.web.services3>
      <applicationSettings>
        <ServicesTestClient_WSE.Properties.Settings>
          <setting name="ServicesTestClient_WSE_ChrisPEmailReference_Email"
            serializeAs="String">
            <value>http://hades.example.local/WebServices/Reports/Email.svc/wseCertificateEndpoint</value>
          </setting>
        </ServicesTestClient_WSE.Properties.Settings>
      </applicationSettings>
    </configuration>

    The security policy from our WSE client app that works in development:
    <policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
      <extensions>
        <extension name="mutualCertificate11Security" type="Microsoft.Web.Services3.Design.MutualCertificate11Assertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <extension name="x509" type="Microsoft.Web.Services3.Design.X509TokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <extension name="requireActionHeader" type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </extensions>
      <policy name="ClientPolicy">
        <mutualCertificate11Security establishSecurityContext="false" renewExpiredSecurityContext="true" requireSignatureConfirmation="true" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="false" ttlInSeconds="300">
          <clientToken>
            <x509 storeLocation="CurrentUser" storeName="My" findValue="Chris Petty" findType="FindBySubjectName" />
          </clientToken>
          <serviceToken>
            <x509 storeLocation="CurrentUser" storeName="TrustedPeople"  findValue="hades" findType="FindBySubjectName" />
          </serviceToken>
          <protection>
            <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
            <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
            <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
          </protection>
        </mutualCertificate11Security>
        <requireActionHeader />
      </policy>
    </policies>

    If I change nothing and move it to the production environment the connection is actively refused since the server only accepts https requests.  If I change the wseCertificateBinding binding on the server to use httpsTransport instead of httpTransport then the client cannot access it with MutualCertificate authentication mode.  What I can't figure out is how to configure it to use CertificateOverTransport.  I need the server to authenticate the client by its certificate and all I can find is info on how to authenticate with username/password.

    Thanks for any help you can give me!
    Chris
    Thursday, January 10, 2008 8:20 PM
  • I have the same problem, did you find the solution ?

    Thanks
    • Edited by Demvin Wednesday, March 11, 2009 8:34 PM typo
    Wednesday, March 11, 2009 8:33 PM
  • Anyone? I have the same problem, WSE3 Client, WCF Service over HTTPS with client certificate as credentials and sign. It's driving me crazy!

    Thanks

    Monday, August 9, 2010 2:25 PM
  • service's and client's web.config?  the endpoint used by the client?  The WSE security policy?
    Monday, August 9, 2010 5:30 PM
  • Here's my policy

      <policy name="MyPolicy">
        <mutualCertificate10Security establishSecurityContext="true" renewExpiredSecurityContext="true" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="false" ttlInSeconds="300">
          <clientToken>
            <x509 storeLocation="CurrentUser" storeName="My" findValue="CN=sdgian.sif.com.ar" findType="FindBySubjectDistinguishedName" />
          </clientToken>
          <serviceToken>
            <x509 storeLocation="CurrentUser" storeName="AddressBook" findValue="CN=sdgian.sif.com.ar" findType="FindBySubjectDistinguishedName" />
          </serviceToken>
          <protection>
            <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
            <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
            <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
          </protection>
        </mutualCertificate10Security>
        <requireActionHeader />
      </policy>

    and my binding on the server (VS2008 w/WCF):

          <customBinding>
            <binding name="WseBinding">
              <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
              <security authenticationMode="MutualCertificate" securityHeaderLayout="Lax"
                messageProtectionOrder="SignBeforeEncrypt"
                messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                requireDerivedKeys="true">
                <secureConversationBootstrap />
              </security>         
              <httpTransport/>         
            </binding>
          </customBinding>

    Calling code in the client (VS2005 w/WSE3)

                Dim srv As New EchoServiceWse

                srv.SetPolicy("MyPolicy")
                txtResult.Text = srv.Echo(txtText.Text, txtFrom.Text)

    This is the exception that I get when calling the service:

    WSE910: An error happened during the processing of a response message, and you can find the error in the inner exception.  You can also find the response message in the Response property.
    InnerException: Security requirements are not satisfied because the security header is not present in the incoming message.

     

    Tuesday, August 10, 2010 2:18 PM
  • Good Day Someone would have to send me a sample? I'm having trouble setting up a WCF server that is compatible with clients WSE3. Since it is required to use SSL. Email: danielpsil@gmail.com Thanks,
    Monday, October 18, 2010 12:38 PM
  • I am also looking for an answer for the scenario where the communication is over SSL.

     

    Did anyone get the scenario working?

    Tuesday, February 22, 2011 10:17 PM