4

I am trying to configure my WCF client to create a SOAP 1.1 request that includes WS-Addressing, WS-Security and TLS.

The security requirements are that the message includes a Username Token, TimeStamp and that the TimeStamp is signed using an included BinarySecurityToken.

I have used the example from the following link to create my WCF client binding. I have slightly modified the the example (see below) so that HTTPS is used as the transport mechanism and the MessageSecurity is based on UsernameOverTransport.

            HttpsTransportBindingElement httpsTransport = new HttpsTransportBindingElement();            
        // the message security binding element will be configured to require 2 tokens:
        // 1) A username-password encrypted with the service token
        // 2) A client certificate used to sign the message

        // Instantiate a binding element that will require the username/password token in the message (encrypted with the server cert)
        TransportSecurityBindingElement messageSecurity = SecurityBindingElement.CreateUserNameOverTransportBindingElement();

        // Create supporting token parameters for the client X509 certificate.
        X509SecurityTokenParameters clientX509SupportingTokenParameters = new X509SecurityTokenParameters();
        // Specify that the supporting token is passed in message send by the client to the service
        clientX509SupportingTokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
        // Turn off derived keys
        clientX509SupportingTokenParameters.RequireDerivedKeys = false;
        // Augment the binding element to require the client's X509 certificate as an endorsing token in the message
        messageSecurity.EndpointSupportingTokenParameters.Endorsing.Add(clientX509SupportingTokenParameters);

        // Create a CustomBinding based on the constructed security binding element.
        return new CustomBinding(messageSecurity, httpsTransport);

The SOAP messages that are generated by this client are very close to meeting the requirements of the service I am calling, the only issue is that the wsa:To address is being signed as well as the TimeStamp address.

Is there a way to specify exactly which WCF headers are signed? As I need to restrict the client only sign the TimeStamp header.

Edward
  • 1,043
  • 10
  • 24
  • Could you please help me https://stackoverflow.com/questions/61632355/c-sharp-connected-soap-service-sign-wsutimestamp-and-wsato-elements-in-th – A_m0 May 08 '20 at 15:24

2 Answers2

0

I know it's an old question but I've been asked about this a couple of times.

I managed to achieve this by specifying the messageVersion as Soap11 instead of Soap11WSAddressing10 and then manually adding the WS-Addresing headers afterwards which avoided the need to manually implement the signing mechanism.

Edward
  • 1,043
  • 10
  • 24
0

With custom message headers you can do this:

//... rest of MessageContract

[MessageHeader(ProtectionLevel = ProtectionLevel.Sign)]
string MyCustomHeader;

//... rest of MessageContract

But I don't believe that will work with your situation since your attempting to sign a soap header that is inserted by your custom binding. To modify these headers you'll likely need to implement the IClientMessageInspector interface and add a custom behavior to the client configuration to sign the TimeStamp header. Not sure how you would access the certificate to do the signing but this may give you a good start.

Sixto Saez
  • 12,610
  • 5
  • 43
  • 51
  • I cannot use the ProtectionLevel settings as I am trying to sign the TimeStamp which is what is referred to infrastructure data in the following link http://msdn.microsoft.com/en-us/library/aa347692.aspx#Y1432.How would I got – Edward May 09 '11 at 21:10
  • Please look at the IClientMessageInspector link in the answer. It shows how to modify the soap message before it is sent to the service. You have access to all the soap headers in the BeforeSendRequest method. You just need to figure out how the digitally sign the wsa:To header item and overwrite the existing one in soap message (this is probably the hard part though). – Sixto Saez May 09 '11 at 21:17
  • 1
    The problem I have is that the WCF binding signs both the wsa:To and wsu:TimeStamp when I require that only the wsu:TimeStamp is signed. I could manipulate message manually to replace the existing signature but I want to minimise the amount of custom manipulation that we do on the SOAP message. I have managed to do this by specifying the messageVersion as Soap11 instead of Soap11WSAddressing10 and then manually adding the WS-Addresing headers afterwards which avoids the need to manually implement the signing mechanism. – Edward May 09 '11 at 22:00
  • 1
    That's an interesting approach. I hadn't thought to play with message versioning. You should answer your own question to get credit for your work. – Sixto Saez May 09 '11 at 23:22