0

I'm trying to do a soap request which has to be signed with a certificate, but i can't get the 'Security' tag in my soap message.

This is the code to set-up a connection

        //Create binding element for security
        var secBE = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
        secBE.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
        secBE.EnableUnsecuredResponse = true;
        secBE.SetKeyDerivation(false);

        secBE.MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;

        secBE.IncludeTimestamp = true; //dit zorgt voor de tijd in de ws security header
        secBE.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15;
        secBE.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampFirst;


        if (secBE.InitiatorTokenParameters is X509SecurityTokenParameters istp)
        {
            istp.X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial;
            istp.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
            istp.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
            istp.X509ReferenceStyle = X509KeyIdentifierClauseType.SubjectKeyIdentifier;
        }

        if (secBE.RecipientTokenParameters is X509SecurityTokenParameters rstp)
        {
            rstp.X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial;
        }

        secBE.EndpointSupportingTokenParameters.Signed.Add(secBE.InitiatorTokenParameters);
        secBE.EndpointSupportingTokenParameters.Signed.Add(secBE.RecipientTokenParameters);

        //Explicit accept secured answers from endpoint
        secBE.AllowSerializedSigningTokenOnReply = true;

        //Create binding element for encoding
        var textBE = new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8);

        //Create binding element for transport
        var httpsBE = new HttpsTransportBindingElement
        {
            RequireClientCertificate = true,
            AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous,
        };

        var cbinding = new CustomBinding();

        cbinding.Elements.Add(secBE);
        cbinding.Elements.Add(textBE);
        cbinding.Elements.Add(httpsBE);

        var endpointIdentity = new DnsEndpointIdentity("mydns");
        var addressHeaderColl = new AddressHeaderCollection();
        var address = new EndpointAddress(new Uri("myuri), endpointIdentity, addressHeaderColl);

        var factory = new ChannelFactory<MyType>(cbinding, address);

        var certClient = new X509Certificate2("locationofcertificate", "password");
        var certService = new X509Certificate2("locationofcertificate");

        //var certificate = _certificateLogic.GetCertificate(_certificateLogic.GetStore());
        //Explicit prevent check on chain of trust
        factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

        factory.Credentials.ClientCertificate.Certificate = certClient;
        factory.Credentials.ServiceCertificate.DefaultCertificate = certService;
        var behavior = new EndpointBehavior();
        factory.Endpoint.Behaviors.Add(behavior);
        return factory.CreateChannel();

This is what i see in my log file (i removed the body, because i think this is not relevant for my question)

    <!-- language: lang-xml -->
    <s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://logius.nl/digipoort/wus/2.0/aanleverservice/1.2/AanleverService_V1_2/aanleverenRequest</a:Action>
    <a:MessageID>urn:uuid:16728029-676f-4624-adef-f7dbd2a594fd</a:MessageID>
    <ActivityId CorrelationId="9009d10b-6bee-48b8-899a-dd7e32b58bd7" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">7269acd3-5479-40e0-ad1f-6d307cd1d134</ActivityId>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo1YlPqhyBVFHif6ypLRU1jsAAAAA4lHfJiPKVUyGQJn81YotjnnW2XDdmrVBskb2185qHkwACQAA</VsDebuggerCausalityData>
  </s:Header>
</s:Envelope> 

I think that the 'secBE' binding is responsible for securing the soap request, but i can't get it to work.

  1. I hope someone can explain why there isn't a security tag in the Soap request.
  • Where's the code that actually signs the message? And why are you adding an `EndpointBehavior` that doesn't appear to do anything? – Hintham May 25 '18 at 09:44
  • See my solution at following posting : https://stackoverflow.com/questions/46722997/saml-assertion-in-a-xml-using-c-sharp/46724392#comment80642919_46724392 – jdweng May 25 '18 at 09:56
  • @HintHam i don't know what i have to do to sign it. And how to combine it with my customer SecurityBindingElement. The EndPointBehavior is for logging purposes. That class implements IEndpointBehavior which has the ApplyClientBehavior method that Adds my MessageInspector to the clientRuntime. – Revenger1986 May 25 '18 at 10:47
  • I think @jdweng has a good alternative solution by templating the soap message. Wcf is hard to tame and has many peculiarities. – Hintham May 25 '18 at 10:51
  • @jdweng Tomorrow i will try to implement your solution. for me it's unclear how i have to send the message to the service. It needs to be done via Https SSL connection. Should i do this with a HttpClient? – Revenger1986 May 28 '18 at 13:58
  • I usually send people to the following codeproject for SSL : https://www.codeproject.com/Articles/1000189/A-Working-TCP-Client-and-Server-With-SSL – jdweng May 28 '18 at 15:09

0 Answers0