How to add transform algorithm ("enveloped-signature")

366 Views Asked by At

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.

1

There are 1 best solutions below

2
On

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.