c # WCF Error in response of Webservice when consuming with SOAP MTOM of Electronic Billing

6

I am consuming a Web Service to send a file

https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica/facturaElectronica.wsdl

But in the debug it returns the following exception:

  

System.ServiceModel.Security.MessageSecurityException: 'Message security check failed.'   InvalidOperationException: Auxiliary token signatures not expected.

     

System.ServiceModel.Security.MessageSecurityException: Message security check error. --- > System.InvalidOperationException: Auxiliary token signatures not expected.    in System.ServiceModel.Security.ReceiveSecurityHeader.ProcessSupportingSignature (SignedXml signedXml, Boolean isFromDecryptedSource)      in System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass (XmlDictionaryReader reader)      in System.ServiceModel.Security.StrictModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses (ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)      in System.ServiceModel.Security.ReceiveSecurityHeader.Process (TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)      in System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore (Message & message, TimeSpan timeout)      in System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage (Message & message, TimeSpan timeout)

To send the file, I do the following:

public string envioFacturaElectronicaMTOM()
{
    const string apiUrl = "https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica";
    byte[] archivo = FileToByteArray(@"c:\temp\ws_f0890900162000000dad3.zip");
    EndpointAddress endpointAddress = new EndpointAddress(new Uri(apiUrl));
    var securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
    securityElement.AllowInsecureTransport = false;
    securityElement.EnableUnsecuredResponse = true;
    securityElement.IncludeTimestamp = false;

    var encodingElement = new MtomMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);



    var transportElement = new HttpsTransportBindingElement();
    var binding = new CustomBinding(securityElement, encodingElement, transportElement);

    facturaElectronicaPortNameClient Service = new facturaElectronicaPortNameClient(binding, endpointAddress);
    Service.ClientCredentials.UserName.UserName = "MiSoftwareID";
    Service.ClientCredentials.UserName.Password = "MiPasswordEnSHA256";

    WSDian.EnvioFacturaElectronica enviofactura = new WSDian.EnvioFacturaElectronica();
    enviofactura.NIT = "MiNIT";
    enviofactura.InvoiceNumber = "124063277";
    enviofactura.IssueDate = Convert.ToDateTime("2018-05-28 20:17:19");
    enviofactura.Document = Convert.FromBase64String(Convert.ToBase64String(archivo));

    EnvioFacturaElectronicaPeticion envioFacturaElectronicaPeticion = new EnvioFacturaElectronicaPeticion();
    envioFacturaElectronicaPeticion.EnvioFacturaElectronicaPeticion1 = enviofactura;

    AcuseRecibo acuseRecibo = new AcuseRecibo();
    acuseRecibo = Service.EnvioFacturaElectronica(envioFacturaElectronicaPeticion.EnvioFacturaElectronicaPeticion1);

    return acuseRecibo.Comments.ToString();
}

In the answer to this question is how I am consuming the web service completely, I do not write it here because it is extensive: c # Consume web service electronic invoicing

When I follow up with fiddler, I see the following in the Request:

POST https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica HTTP/1.1
MIME-Version: 1.0
Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:1a31b7a4-bb88-4bd7-aa99-6bfca75980a0+id=1";start-info="text/xml"
SOAPAction: ""
Host: facturaelectronica.dian.gov.co
Content-Length: 9191
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive


--uuid:1a31b7a4-bb88-4bd7-aa99-6bfca75980a0+id=1
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
	<s:Header>
		<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPonyxdQ1ypqsgAAAAAInUwvSubfkWtkosj7GNjAU+JUra/JWZAnJwNPpSrhZUACQAA</VsDebuggerCausalityData>
		<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
			<o:UsernameToken u:Id="uuid-dceca3e0-7764-477b-aac4-3e5ad3303a9f-1">
				<o:Username><!--Removed--></o:Username>
				<o:Password><!--Removed--></o:Password>
			</o:UsernameToken>
		</o:Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
		<EnvioFacturaElectronicaPeticion xmlns="http://www.dian.gov.co/servicios/facturaelectronica/ReportarFactura">
			<NIT><!--Removed--></NIT>
			<InvoiceNumber>124063277</InvoiceNumber>
			<IssueDate>2018-05-28T20:17:19</IssueDate>
			<Document><xop:Include href="cid:http://tempuri.org/1/636719021136260437" xmlns:xop="http://www.w3.org/2004/08/xop/include"/></Document>
		</EnvioFacturaElectronicaPeticion>
	</s:Body>
</s:Envelope>
--uuid:1a31b7a4-bb88-4bd7-aa99-6bfca75980a0+id=1
Content-ID: <http://tempuri.org/1/636719021136260437>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream

PK    x M h   .c     face_f0890900161000000faf3.xml |ۖ Ⱥ O Ⱦ 9 39
--uuid:1a31b7a4-bb88-4bd7-aa99-6bfca75980a0+id=1--

And the response I receive is as follows:

HTTP/1.1 200 OK
Date: Fri, 07 Sep 2018 12:28:33 GMT
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="----=_Part_504669_2132088323.1536323314599"
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Set-Cookie: TS0133d910=01ca0e1ef64130a10e8ff09c341631cb87ffd0b88debb404b553072ef7b937149aeae0ee703398a88c3adec21a15c42b7a1d9ebafc; Path=/
Content-Length: 3256

------=_Part_504669_2132088323.1536323314599
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
	<SOAP-ENV:Header>
		<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" SOAP-ENV:mustUnderstand="1">
			<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-478012">
				<ds:SignedInfo>
					<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
						<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="SOAP-ENV"/>
					</ds:CanonicalizationMethod>
					<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
					<ds:Reference URI="#id-478011">
						<ds:Transforms>
							<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
								<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/>
							</ds:Transform>
						</ds:Transforms>
						<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
						<ds:DigestValue>gPOXTVuXDw2ktXu3Fiyjoz35JwY=</ds:DigestValue>
					</ds:Reference>
				</ds:SignedInfo>
				<ds:SignatureValue>e7AOmryll5EXw3euAOlO2CwL+N3wpR+QHz8Zmlz+hBFZ7kmQ9QXkupO+MUkDrnHu/MsOZr7Q0j60heMbM4u3yIiTRPE0HsEOV1BQ/+v0LX+XSGo1EiHlcYbEo8Yn+aHFmR4z81TV8TycRXMBUoyJXl2Y/yLjFPH8TptpKLagEOYgcJQ340Cw7rVBfG+tuVwU388F/MDiv/vRhIjpHViSHSP8C7xO5NZvNoGsg5f66ATzkwkB4wmeAmHud3Mbuj7Vdq3Sw==</ds:SignatureValue>
				<ds:KeyInfo Id="KI-0ACB9EF7167DC955151536323314584358508">
					<wsse:SecurityTokenReference wsu:Id="STR-0ACB9EF7167DC955151536323314584358509">
						<ds:X509Data>
							<ds:X509IssuerSerial>
								<ds:X509IssuerName>CN=AC SUB CERTICAMARA,O=CERTICAMARA S.A,OU=NIT 830084433-7,C=CO,ST=DISTRITO CAPITAL,L=BOGOTA,STREET=www.certicamara.com</ds:X509IssuerName>
								<ds:X509SerialNumber>91436926122049919406185072624124</ds:X509SerialNumber>
							</ds:X509IssuerSerial>
						</ds:X509Data>
					</wsse:SecurityTokenReference>
				</ds:KeyInfo>
			</ds:Signature>
			<wsu:Timestamp wsu:Id="TS-478010">
				<wsu:Created>2018-09-07T12:28:34.584Z</wsu:Created>
				<wsu:Expires>2018-09-07T12:33:34.584Z</wsu:Expires>
			</wsu:Timestamp>
			<wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsu:Id="SC-478009"/>
		</wsse:Security>
	</SOAP-ENV:Header>
	<SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-478011">
		<ns2:EnvioFacturaElectronicaRespuesta xmlns:ns2="http://www.dian.gov.co/servicios/facturaelectronica/ReportarFactura" xmlns:ns3="http://www.dian.gov.co/servicios/facturaelectronica/ConsultaDocumentos" xmlns:ns4="http://www.dian.gov.co/servicios/facturaelectronica/VersionDespliegue">
			<ns2:Version>Componente DIAN</ns2:Version>
			<ns2:ReceivedDateTime>2018-09-07T07:28:34.392-05:00</ns2:ReceivedDateTime>
			<ns2:ResponseDateTime>2018-09-07T07:28:34.583-05:00</ns2:ResponseDateTime>
			<ns2:Response>200</ns2:Response>
			<ns2:Comments>Ejemplar recibido exitosamente pasará a verificación.</ns2:Comments>
		</ns2:EnvioFacturaElectronicaRespuesta>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
------=_Part_504669_2132088323.1536323314599--
--------------------------------------------------
caf
------=_Part_67971_1574199767.1536252188646

I do not know what may be happening or how should I receive the answer so that the C # does not throw me the exception?

Thank you.

    
asked by Felipe Taborda 07.09.2018 в 15:21
source

1 answer

5

The exception occurs because the unsigned request is sent <signature> , but the response is signed. it seems that .net expects an unsigned response.

The way I found to solve it was not the best, but it is functional and allows us to continue with the process of receiving the response and its corresponding process. I had to use a CustomEncoder , in order to process the response before it arrived to remove the entire signature.

I base myself on this article: link and make modifications to adapt it to what I need.

The section that you modify of the DLL that you create based on the previous article stayed like this:

public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
    {
        //Convert the received buffer into a string
        byte[] incomingResponse = buffer.Array;
        incomingResponse = RemoveSignatures(incomingResponse);
        ........

The class I created RemoveSignatures removes the signature and returns the response without signature:

private byte[] RemoveSignatures(byte[] stream)
    {
        string stream2 = Encoding.UTF8.GetString(stream);           
        stream2 = stream2.Replace("
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
    {
        //Convert the received buffer into a string
        byte[] incomingResponse = buffer.Array;
        incomingResponse = RemoveSignatures(incomingResponse);
        ........
", ""); Regex x = new Regex("(\<SOAP-ENV:Header\>)(.*?)(\</SOAP-ENV:Header\>)"); string repl = ""; stream2 = x.Replace(stream2, "$1" + repl + "$3"); byte[] streamNuevo = Encoding.ASCII.GetBytes(stream2); return streamNuevo; }

This class creates it with the help of this answer that I found here: link

In this way .Net no longer generates the exception and allows you to process the Response.

As I mentioned at the beginning, this solution is too hack for my taste, but it is functional. I hope to find a better way, if so, I'll publish it.

I hope it helps someone else.

    
answered by 26.09.2018 / 14:55
source