title: How to make WCF client sign SecurityTokenReference:Reference
body: <p>I need to create a WCF client who calls a bea webservice.</p>
  
  <p>I keep getting this response from the webservice:</p>
  
  <p><strong>Could not validate signature using any of the supported token types</strong></p>
  
  <p>So I turn my attention to the signature part of the client&lt;->service communication:</p>
  
  <p>Part of the wsdl from the webservice:</p>
  
  <pre><code>&lt;s0:Policy s1:Id="Sign.xml"&gt;
  &lt;wssp:Integrity xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
                  xmlns:wssp="http://www.bea.com/wls90/security/policy"
                  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
    &lt;wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;
    &lt;wssp:CanonicalizationAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
    &lt;wssp:Target&gt;
      &lt;wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
      &lt;wssp:MessageParts Dialect="http://www.bea.com/wls90/security/policy/wsee#part"&gt; 
      wls:SystemHeaders()
    &lt;/wssp:MessageParts&gt;
    &lt;/wssp:Target&gt;
    &lt;wssp:Target&gt;
      &lt;wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
      &lt;wssp:MessageParts Dialect="http://www.bea.com/wls90/security/policy/wsee#part"&gt; 
      wls:SecurityHeader(wsu:Timestamp)
    &lt;/wssp:MessageParts&gt;
    &lt;/wssp:Target&gt;
    &lt;wssp:Target&gt;
      &lt;wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
      &lt;wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part"&gt;
    wsp:Body()
    &lt;/wssp:MessageParts&gt;
    &lt;/wssp:Target&gt;
    &lt;wssp:SupportedTokens&gt;
      &lt;wssp:SecurityToken 
        IncludeInMessage="true" 
        TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"&gt;
        &lt;wssp:TokenIssuer&gt;REMOVED&lt;/wssp:TokenIssuer&gt;
      &lt;/wssp:SecurityToken&gt;
    &lt;/wssp:SupportedTokens&gt;
  &lt;/wssp:Integrity&gt;
  &lt;wssp:MessageAge Age="60" xmlns:wssp="http://www.bea.com/wls90/security/policy"/&gt;
  </code></pre>
  
  <p></p>
  
  <p>From the wsdl i understand that I must sign:</p>
  
  <ol>
  <li>SystemHeaders (my real problem)</li>
  <li>Timestamp (did that)</li>
  <li>Body (did that, and also encrypted it)</li>
  </ol>
  
  <p>I have working code (using microsoft.web.services3) who produce this soap:</p>
  
  <pre><code>&lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
      &lt;SignedInfo&gt;
        &lt;ds:CanonicalizationMethod 
          Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
          xmlns:ds="http://www.w3.org/2000/09/xmldsig#" /&gt;
        &lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&gt;
        &lt;Reference URI="#Timestamp-fc23bf88-381b-4f2b-b992-ff07b41b5c38"&gt; &lt;!--This is the timestamp--&gt;
          &lt;Transforms&gt;
            &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
          &lt;/Transforms&gt;
          &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
          &lt;DigestValue&gt;Removed&lt;/DigestValue&gt;
        &lt;/Reference&gt;
        &lt;Reference URI="#Id-4b4f1377-eac0-4db0-b334-384d7b14e286"&gt; &lt;!--This is the encrypted body--&gt;
          &lt;Transforms&gt;
            &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
          &lt;/Transforms&gt;
          &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
          &lt;DigestValue&gt;Removed&lt;/DigestValue&gt;
        &lt;/Reference&gt;
        &lt;Reference URI="#SecurityToken-dcb8a392-5907-4432-80c6-cbe8f29a6117"&gt; &lt;!--This is the SecurityTokenReference:Reference--&gt;
          &lt;Transforms&gt;
            &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
          &lt;/Transforms&gt;
          &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
          &lt;DigestValue&gt;Removed&lt;/DigestValue&gt;
        &lt;/Reference&gt;
      &lt;/SignedInfo&gt;
      &lt;SignatureValue&gt;Removed&lt;/SignatureValue&gt;
      &lt;KeyInfo&gt;
        &lt;wsse:SecurityTokenReference&gt;
          &lt;wsse:Reference 
            URI="#SecurityToken-dcb8a392-5907-4432-80c6-cbe8f29a6117" 
            ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" /&gt;
        &lt;/wsse:SecurityTokenReference&gt;
      &lt;/KeyInfo&gt;
    &lt;/Signature&gt;
  &lt;/wsse:Security&gt;
  &lt;/soap:Header&gt;
  &lt;soap:Body wsu:Id="Id-4b4f1377-eac0-4db0-b334-384d7b14e286"&gt;
  &lt;xenc:EncryptedData 
   Id="Enc-8b5b4ef4-1c12-409b-8159-dec2889a8fa8" 
   Type="http://www.w3.org/2001/04/xmlenc#Content" 
   xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"&gt;
    &lt;xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /&gt;
    &lt;xenc:CipherData&gt;
      &lt;xenc:CipherValue&gt;Removed&lt;xenc:CipherValue&gt;
    &lt;/xenc:CipherData&gt;
  &lt;/xenc:EncryptedData&gt;
  &lt;/soap:Body&gt;
  </code></pre>
  
  <p>I have promised to make this work using WCF, so microsoft.web.services3 is not an option. Sorry.</p>
  
  <p>I have created the proxy using svcutil. No sweat. Only change I have made to the proxy by hand is that I have appended </p>
  
  <pre><code>, ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign
  </code></pre>
  
  <p>to the System.ServiceModel.ServiceContractAttribute</p>
  
  <p>My current code produces this sign part:</p>
  
  <pre><code>&lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
      &lt;SignedInfo&gt;
        &lt;CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
        &lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;
        &lt;Reference URI="#_1"&gt; &lt;!--This is the body--&gt;
          &lt;Transforms&gt;
            &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
          &lt;/Transforms&gt;
          &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
          &lt;DigestValue&gt;Removed&lt;/DigestValue&gt;
        &lt;/Reference&gt;
        &lt;Reference URI="#uuid-e7f22d2b-5a91-421a-aced-df7ab8a92f8d-1"&gt; &lt;!--This is the timestamp--&gt;
          &lt;Transforms&gt;
            &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
          &lt;/Transforms&gt;
          &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
          &lt;DigestValue&gt;Removed&lt;/DigestValue&gt;
        &lt;/Reference&gt;
      &lt;/SignedInfo&gt;
      &lt;SignatureValue&gt;Removed&lt;/SignatureValue&gt;
      &lt;KeyInfo&gt;
        &lt;o:SecurityTokenReference&gt;
          &lt;o:Reference 
            ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" 
            URI="#uuid-3b0e28b3-d47f-4eb2-ab0a-77f94dd76af0-2"/&gt;
        &lt;/o:SecurityTokenReference&gt;
      &lt;/KeyInfo&gt;
    &lt;/Signature&gt;
  &lt;/o:Security&gt;
  &lt;/s:Header&gt;
  &lt;s:Body u:Id="_1" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
   &lt;e:EncryptedData 
    Id="_2" 
    Type="http://www.w3.org/2001/04/xmlenc#Content" 
    xmlns:e="http://www.w3.org/2001/04/xmlenc#"&gt;
    &lt;e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/&gt;
    &lt;e:CipherData&gt;&lt;e:CipherValue&gt;Removed&lt;/e:CipherValue&gt;&lt;/e:CipherData&gt;
  &lt;/e:EncryptedData&gt;
  &lt;/s:Body&gt;
  &lt;/s:Envelope&gt;
  </code></pre>
  
  <p>from my app.config:</p>
  
  <pre><code>  &lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;customBinding&gt;
          &lt;binding name="testBinding"&gt;
            &lt;textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" 
                                 messageVersion="Soap11" writeEncoding="utf-8"&gt;
              &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" 
                            maxArrayLength="16384" maxBytesPerRead="4096" 
                            maxNameTableCharCount="16384"/&gt;
            &lt;/textMessageEncoding&gt;
            &lt;httpTransport manualAddressing="false" maxBufferPoolSize="524288" 
                           maxReceivedMessageSize="65536" allowCookies="false" 
                           authenticationScheme="Anonymous" bypassProxyOnLocal="false" 
                           hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" 
                           maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" 
                           realm="" transferMode="Buffered" 
                           unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true"/&gt;
          &lt;/binding&gt;
        &lt;/customBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt;
        &lt;endpoint address="http://url.com/testservice/testservicePort" binding="customBinding" 
                  bindingConfiguration="testBinding" 
                  contract="testservicePortType" 
                  name="testservicePort"/&gt;
      &lt;/client&gt;
    &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>I configure the CustomBinding in code like this:</p>
  
  <pre><code>    private static CustomBinding CreateCustomBinding()
      {
          var customBinding = new CustomBinding();
  
          SecurityBindingElement securityBindingElement = SecurityBindingElement.CreateMutualCertificateBindingElement(
                  MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
  
          AsymmetricSecurityBindingElement asymmetricSecurityBindingElement =
              (AsymmetricSecurityBindingElement)securityBindingElement;
  
          asymmetricSecurityBindingElement.SetKeyDerivation(false);
  
          asymmetricSecurityBindingElement.EnableUnsecuredResponse = true;
  
          asymmetricSecurityBindingElement.AllowInsecureTransport = true;
          asymmetricSecurityBindingElement.AllowSerializedSigningTokenOnReply = true;
  
          asymmetricSecurityBindingElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15;
  
          asymmetricSecurityBindingElement.IncludeTimestamp = true;
          asymmetricSecurityBindingElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
          asymmetricSecurityBindingElement.RequireSignatureConfirmation = false;
  
          asymmetricSecurityBindingElement.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampFirst;
  
          customBinding.Elements.Clear();
  
          customBinding.Elements.Add(asymmetricSecurityBindingElement);
  
          customBinding.Elements.Add(new TextMessageEncodingBindingElement()
          {
              MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11,
              AddressingVersion.None),
              WriteEncoding = new System.Text.UTF8Encoding()
          });
  
          HttpTransportBindingElement httpbinding = new HttpTransportBindingElement();
          httpbinding.AuthenticationScheme = AuthenticationSchemes.Anonymous;
          httpbinding.MaxReceivedMessageSize = 1024 * 1024;
          customBinding.Elements.Add(httpbinding);
          return customBinding;
      }
  </code></pre>
  
  <p>I have tried to understand what happens in the microsoft.web.services3 code who works (I havent written it), and it seems like the author completely rewrites the securityheader. This doesnt seem like the best solution (but maybe the only?)</p>
  
  <p>Could anyone help me?</p>