0

I am stuck with a call to soap service which needs "enveloped-signature" as transform algorithm. And i am getting "xml-exc-c14n#". I am using custom binding to initialize the client for WCF request.

Update: In the above example, I was trying without Message Inspectors. So I have tried both ways. 1. using WCF call but then I am unable to change the transform algorithm to "enveloped-signature". 2. I tried using Inspector where I try to create signed XML document and add this to the request message. Like explained in this example Message inspectors- WCF call I failed in both.

Below is the code i am using for WCF call without Inspector

var b = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
sec.MessageSecurityVersion =
    MessageSecurityVersion.
    WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12;
sec.IncludeTimestamp = false;
sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
sec.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic256Sha256;
X509SecurityTokenParameters x509Params = new X509SecurityTokenParameters
{
    X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial,
    RequireDerivedKeys = false,
    InclusionMode = SecurityTokenInclusionMode.Once,
    ReferenceStyle = SecurityTokenReferenceStyle.Internal
};
((AsymmetricSecurityBindingElement)sec).InitiatorTokenParameters = x509Params;


b.Elements.Add(sec);
b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
b.Elements.Add(new HttpsTransportBindingElement() { });

Please help me out if you have got any idea.

Djordje Nedovic
  • 559
  • 8
  • 20
NS1
  • 21
  • 1
  • 6
  • If your question is to operate on the request message, you can refer to:https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/message-inspectors – Theobald Du Dec 18 '20 at 08:14
  • @TheobaldDu Yes it's about changing the message as well. So i do use this event BeforeSendRequest. But the signed xml which i try to use to replace the existing request(Message) is not copied exactly. So the signed xml string changes when i create message. – NS1 Dec 22 '20 at 12:35
  • @TheobaldDu In the above example i was trying without Inspectors. So i have tried both ways. 1. using wcf call but then i am unable to change the transform algorithm to "enveloped-signature". 2. I tried using Inspector where i try to create signed xml document and add this to the request message. I failed in both. – NS1 Dec 22 '20 at 12:38

1 Answers1

0

On the client side, by implementing the IClientMessageInspector interface to intercept SOAP messages.

 public class ClientMessageLogger : IClientMessageInspector
{
    public object AfterReceiveRequest(ref Message reply, object correlationState)
    {
        MessageHeader header = MessageHeader.CreateHeader("UserAgent", "http://User", "User1");
        reply.Headers.Add(header);
        return null;
    }

    public void BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageHeader header1 = MessageHeader.CreateHeader("Testreply", "http://Test", "Test");
        request.Headers.Add(header1);
    }
}
[AttributeUsage(AttributeTargets.Interface)]
public class CustomBehavior : Attribute, IContractBehavior
{
    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        return;
    }
    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.MessageInspectors.Add(new CustomMessageInspector());
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
        return;
    }
}

Then, apply the CustContractBehavior feature to the service interface.

     [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
        [CustomBehavior]
     public interface IDemo

When the client sends a request to the server, it will call BeforeSendRequest, and when the client receives the server reply message, it will call AfterReceiveReply.

Theobald Du
  • 824
  • 4
  • 7
  • Hi I am implementing this. Sorry if i am not clear. But the problem i am facing in here is that i need to replace whole message not a single header. Because it's a signed XML which contains security header with certificate and all. I can sign the xml body separately (valid signed xml as string). Now i want to use that as request message. But when i try to create a message out of that signed xml, it changes and it's not a valid xml anymore. – NS1 Dec 23 '20 at 08:43
  • Yes, the message interceptor can only modify the message header, and the modification of the message body is not allowed, because the structure of the message body is determined by the definition of the service contract, and the modification will cause the verification of the message content to fail. If you want to modify the message, MessageFormatter allows custom SOAP messages. – Theobald Du Dec 23 '20 at 09:20