none
How to sign (and validate the signature) a custom SOAP header in WCF programatically? RRS feed

  • Question

  • Hello,

    I am writing a sample WCF client application which should insert custom SOAP header into SOAP message and also sign one property inside the custom SOAP header.

    Below is the custom header type that I would like to insert in the SOAP header and sign only one property (ConsumerAplicationId) inside the header.

    public class ClientRequestHeader
    {
            public string ConsumerApplicationId { get; set; }

            public string ConsumerTransactionId { get; set; }
    }

    On the other hand, I would also like to write the WCF service which should validate the digital signature inserted by the above WCF client application. 

    Please suggest on how to do this?


    Sunday, February 15, 2015 6:28 PM

Answers

  • I was able to solve this problem by writing a Message Inspector.

    At the consumer/client side, in the BeforeSendRequest method of IClientMessageInspector, I am signing the required part of the message with the help of System.Security.Cryptography.Xml.SignedXml class.

    Similarly on the service side, in the AfterReceiveRequest method of IDispatchMessageInspector, I am validating the signature again with the help of System.Security.Cryptography.Xml.SignedXml class.

    Sunday, April 12, 2015 10:13 AM

All replies

  • Hi Sampath Kumar Kamati,

    Based on your description, I know that you want to sign the soap header, then maybe you can try to do the following in the message contract:

    [MessageHeader(ProtectionLevel=System.Net.Security.ProtectionLevel.Sign)]

    To better understand the protection level feature, please take a look at a MSDN document below.

    #Understanding Protection Level:
    http://msdn.microsoft.com/en-us/library/aa347692.aspx

    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.


    Monday, February 16, 2015 3:45 AM
    Moderator
  • Hi Amy,

    Thank you for your response. In my scenario, the message header is a complex type with two string properties inside it. I need only one property inside that header type to be signed.

    Below is my header class - ClientRequestHeader

    [DataContract] public class ClientRequestHeader { //Only this property needs to be signed. [DataMember] public string ConsumerApplicationId { get; set; } [DataMember] public string ConsumerTransactionId { get; set; } }

    Hence, If I use, the MessageHeader attribute with the protection level as sign, entire ClientRequestHeader will be signed instead of only one property inside that type.

    Given below is my full and complete message contract, which has one Header and Body property. The header is of type ClientRequestHeader (mentioned above). In that header I just need only one property (ConsumerApplicationId) to be signed.

        [MessageContract]
        public class MyMessageContract
        {
            [MessageHeader]
            public ClientRequestHeader Header { get; set; }
            
            [MessageBodyMember]
            public string AccountNumber { get; set; }
        }


    Monday, February 16, 2015 4:37 AM
  • Have you tried a custom binding with SymmetricSecurityBindingElement and X509SecurityTokenParameters? I don't know if it will produce exactly the same format as you require. But give it a try. Refer to http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/55563b1b-b529-4041-a096-1b2176d4f336/ for a sample.

    If that still doesn't work, try to use a message inspector: http://msdn.microsoft.com/en-us/library/aa717047.aspx.

    If nothing works, there's always a last solution: Manually construct the SOAP envelop, and send it using HttpWebRequest. It can be difficult to sign the message, though.


    Mark if helps
    Friday, March 6, 2015 9:39 AM
  • I was able to solve this problem by writing a Message Inspector.

    At the consumer/client side, in the BeforeSendRequest method of IClientMessageInspector, I am signing the required part of the message with the help of System.Security.Cryptography.Xml.SignedXml class.

    Similarly on the service side, in the AfterReceiveRequest method of IDispatchMessageInspector, I am validating the signature again with the help of System.Security.Cryptography.Xml.SignedXml class.

    Sunday, April 12, 2015 10:13 AM