none
WCF Client consuming WS-Security webservice RRS feed

  • Question

  • I managed to consume a java based web service (third party) with WS-Security 1.1 protocol. The web service needs only to be signed over a x509 certificate, not encrypted. But I'm getting this error:

    The signature confirmation elements cannot occur after the primary signature.

    The captured server response package looks like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soapenv:Header>
            <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true">
                <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-501">
                    <ds:SignedInfo>
                        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                        <ds:Reference URI="#id-502">
                            <ds:Transforms>
                                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            </ds:Transforms>
                            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                            <ds:DigestValue>...</ds:DigestValue>
                        </ds:Reference>
                        <ds:Reference URI="#SigConf-500">
                            <ds:Transforms>
                                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            </ds:Transforms>
                            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                            <ds:DigestValue>...</ds:DigestValue>
                        </ds:Reference>
                    </ds:SignedInfo>
                    <ds:SignatureValue>
                    ...
                    </ds:SignatureValue>
                    <ds:KeyInfo Id="KeyId-...">
                        <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-...">
                            <ds:X509Data>
                                <ds:X509IssuerSerial>
                                    <ds:X509IssuerName>CN=COMODO RSA Organization Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB</ds:X509IssuerName>
    
                                    <ds:X509SerialNumber>...</ds:X509SerialNumber>
                                </ds:X509IssuerSerial>
                            </ds:X509Data>
                        </wsse:SecurityTokenReference>
                    </ds:KeyInfo>
                </ds:Signature>
                <wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" Value="..." wsu:Id="SigConf-500"/>
            </wsse:Security>
        </soapenv:Header>
        <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-502">
            <altaClienteResponse xmlns="...">
                <altaClienteReturn>
                    <codigoError>7</codigoError>
                    <descripcionError>El código de banco no es válido.</descripcionError>
                    <idTransaccion xsi:nil="true"/>
                </altaClienteReturn>
            </altaClienteResponse>
        </soapenv:Body>
    </soapenv:Envelope>

    The server is responding what it should but my app seems not to be interpreting it correctly. It seems that the <wsse11:SignatureConfirmation .../> tag must be before <ds:Signature></ds:Signature>tag.

    I couldn't find any reference to a order standard of this.

    My code

    try
    {
        var certificate = new X509Certificate2(@"C:\Users\...\cert.pfx", PassKeyStore);
    
        var binding = new CustomBinding();
    
        var security = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
    
        security.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters
        {
            InclusionMode = SecurityTokenInclusionMode.Never,
            ReferenceStyle = SecurityTokenReferenceStyle.Internal,
        });
    
        security.RecipientTokenParameters.InclusionMode = SecurityTokenInclusionMode.Never;
        security.RecipientTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
    
        security.MessageSecurityVersion =
            MessageSecurityVersion.
                WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
        security.IncludeTimestamp = false;
        security.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;    
    
        security.RequireSignatureConfirmation = true;
        security.AllowSerializedSigningTokenOnReply = true;   
    
        binding.Elements.Add(security);
        binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
        binding.Elements.Add(new HttpsTransportBindingElement());    
    
        var client = new SistarbancService.WsMediosPagoClient(binding, new EndpointAddress(new Uri(UrlSistarbanc), new DnsEndpointIdentity("..."), new AddressHeaderCollection()));    
    
        client.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("C:\\Users\\...\\servidor.cer");
        client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
            System.ServiceModel.Security.X509CertificateValidationMode.None;
        client.ClientCredentials.ClientCertificate.Certificate = certificate;
    
        client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
    
        var response = await client.altaClienteAsync("XXX", "0", "0", "0", "0", "0");
    }
    catch (Exception ex)
    {
    
    }

    Friday, July 27, 2018 6:26 PM

All replies

  • Hi glorieto,

    I'm trying to involve some senior engineers into this issue and it will take some time. Your patience will be greatly appreciated.
     
    Sorry for any inconvenience and have a nice day!

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, July 31, 2018 5:19 AM
  • Thanks. Please report on any news you have.
    Tuesday, November 6, 2018 6:05 PM
  • Tao, are there any docs about WS-Security standards?
    Wednesday, December 5, 2018 3:29 PM