Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Colaboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #21  
Antiguo 03-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Para poder compilar y empezar a hacer pruebas, lo "solucioné" con un "array of string".

No sé si será la solución, pero al menos podremos empezar a probar cosas y poco a poco ir avanzando.
Responder Con Cita
  #22  
Antiguo 03-11-2015
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.003
Poder: 26
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Cita:
Empezado por iMia Ver Mensaje
SOAP (Simple Object Access Protocol) no es exclusivo de windows... es un protocolo de comunicaciones, para el intercambio de información... Inicialmente en xml...
Gracias por la info.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #23  
Antiguo 04-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 143
Poder: 15
iMia Va por buen camino
Thumbs up

bueno os informo de los progresos que estamos haciendo con espinete...

Empezado por espinete
Cita:
Creo que tengo algo...

He buscado por cómo añadir headers a la petición soap antes de hacer el envío y encontré un post en StackOverflow (en Delphi):
http://stackoverflow.com/questions/2...814937#2814937

Concretamente, en el evento BeforeExecute del componente HTTPRIO, obtenemos la petición que se va a enviar y la podemos "cambiar" sobre la marcha. Precisamente este usuario necesitaba hacer algo parecido a lo que intentamos nosotros (añadir la sección headers).

Luego he usado ese mismo evento para obtener lo que envía nuestra aplicación al webservice, en un Memo, y efectivamente, falta la sección <soapenv:Header> en el XML.

Bien

No obstante, no creo que esta sea la forma de conseguirlo. El XML podemos rellenarlo antes (incrustar la sección header con la firma, certificado, etc.). Lo que no me parece muy lógico es tener que firmar 2 veces el XML (una para firmar la factura y otra para el header), pero bueno, supongo que es normal.
Sí, aunque lo normal sería algo así...


Código Delphi [-]
var
  sphdr: TSOAPHEADERS;
  htpr: THTTPRIO;
  ws: SSPPWebServiceProxyPort;
...
begin
  sphdr := TSOAPHEADERS.create;
  htpr := THTTPRIO.create(self);
  htpr.SOAPHeaders.Send(sphdr);
  ws := GetSSPPWebServiceProxyPort(false, '', htpr);
...

Pero hay que enviar en la cabecera, todo el mensaje entero firmado...
por lo que hay que parsearlo o meterlo a mano antes de enviarlo con el evento BeforeExecute del httprio.
Es decir, en el evento, se coge el mensaje que se va a enviar (lo que hay en body, aunque contenga documentos firmados o no...), se firma, y se mente en la cabecera.
De esta forma ellos pueden comprobar que el mensaje que les llega, no está manipulado, ya que les llega sin firmar y firmado, comprueba la firma y si es correcta, al abrirlo, lo comparan con lo enviado... si es igual, está todo correcto y continúan...

Por lo que para ello hay que definir la función que capturará en evento...

Código Delphi [-]
 
  procedure HTTPRIO_BeforeExecute(const MethodName: string; SOAPRequest: TStream);

definir el httprio, asignarle el evetno y utilizarlo como vehículo del webservice...

Código Delphi [-]
var
  ws: SSPPWebServiceProxyPort;
  ...
begin
  htpr := THTTPRIO.create(self);
  htpr.OnBeforeExecute := HTTPRIO_BeforeExecute;

  ws := GetSSPPWebServiceProxyPort(false, '', htpr);
...

el evento se define tal que...

Código Delphi [-]
procedure TMDIMainForm.HTTPRIO_BeforeExecute(const MethodName: string; SOAPRequest: TStream);
var
  xmlCall: TXMLDocument;
begin
   try
      // Posicionarse al inicio del stream
      SOAPRequest.Position := 0;
      // pasar el stream a un xmlDoc... o donde se quiera...
      xmlCall.LoadFromStream(SOAPRequest);
      // Firmarlo y meterlo en la cabecera...

...
Responder Con Cita
  #24  
Antiguo 04-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Hola

Bien, vamos avanzando...

He conseguido añadir una cabecera a la petición, y gracias al evento BeforeExecute, puedo ver que efectivamente ahora el XML sí tiene sección cabecera:

Código:
<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:Soap.InvokeRegistry">
<NS1:TSOAPHeader xsi:type="NS1:TSOAPHeader"/>
Casi lloro.

Bien. Yo lo he hecho de otra forma, no sé si ves algún problema:

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var facturasspp : SSPPFactura;
    fichero_fac : SSPPFicheroFactura;
    answ : SSPPResultadoEnviarFactura;
    PO:SSPPWebServiceProxyPort;

    htpr: THTTPRIO;
    sphdr: TSOAPHEADER;
    ws: SSPPWebServiceProxyPort;
begin
    if opendialog1.Execute then
    begin
        //Creamos los headers, necesarios para la petición SOAP
        sphdr := TSOAPHEADER.create;

        //Aquí rellenaríamos la sección header, pero no sé si es el mejor lugar.        

        PO := GetSSPPWebServiceProxyPort(FALSE, '', nil);
        facturasspp := ssppfactura.Create;
        facturasspp.correo := 'prueba@miemail.com';
        fichero_fac := ssppficherofactura.Create;
        fichero_fac.nombre := extractfilename(opendialog1.FileName);
        fichero_fac.factura := '72345';
        fichero_fac.mime := 'application/xml';
        facturasspp.fichero_factura := fichero_fac;

        //Aquí asignamos los headers que hemos creado a nuestra petición soap
        HTTPRIO1.SOAPHeaders.Send(sphdr);

        try
            answ := (HTTPRIO1 as SSPPWebServiceProxyPort).enviarFactura(facturasspp);
        except
            on e:exception do showmessage(e.Message);
        end;
    end;

end;

Tu código es diferente, creo que utilizas un XMLDocument que contendría las cabeceras ya rellenadas?

Ahora lo complicado es cómo meter el mensaje FIRMADO en la cabecera... ¿A mano?

Por ejemplo, en la petición SOAP que uso para pruebas, el body es este:

Código:
<SOAP-ENV:Body xmlns:NS2="https://webservice.face.gob.es" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<NS2:enviarFactura>
  <facturaWS href="#2"/>
</NS2:enviarFactura>
<NS2:SSPPFactura id="2" xsi:type="NS2:SSPPFactura">
  <correo xsi:type="xsd:string">prueba@miemail.com</correo>
  <fichero_factura href="#3"/>
  <ficheros_anexos xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS2:SSPPFicheroAnexo[0]"/>
</NS2:SSPPFactura>
<NS2:fichero_factura id="3" xsi:type="NS2:SSPPFicheroFactura">
  <factura xsi:type="xsd:string">72345</factura>
  <nombre xsi:type="xsd:string">Factura 177.xml</nombre>
  <mime xsi:type="xsd:string">application/xml</mime>
</NS2:fichero_factura>
Cómo se "firma" ese trozo de texto?

Aquí tengo una muestra de petición "REAL" sacada de la documentación, que debería servirnos como ejemplo, aunque a estas alturas ya dudo de lo que puede servir y lo que no.
Le he quitado la parte de los ficheros anexos (por ahora) para simplificarlo un poco.

Código:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="https://webservice.face.gob.es">

<soapenv:Header>

    <!-- // Security Content -->

</soapenv:Header>

<soapenv:Body>

<web:enviarFactura soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<facturaWS xsi:type="sspp:SSPPFactura">

    <!--You may enter the following 3 items in any order-->
      <correo xsi:type="xsd:string">XXXX correo electronicoXXXX</correo>
      <fichero_factura xsi:type="sspp:SSPPFicheroFactura">
    
      <!--You may enter the following 3 items in any order-->
      <factura xsi:type="xsd:string"> _contenido enbase_64 del fichero factura_ </factura>
      <nombre xsi:type="xsd:string"> _nombre del ficherofactura_ </nombre>
      <mime xsi:type="xsd:string"> _mimeType del ficherofactura_ </mime>
    </fichero_factura>

</facturaWS>
</web:enviarFactura>

</soapenv:Body>
</soapenv:Envelope>
Y el ejemplo de Security-Content que pone en la documentación es este (lo que va dentro del header):

Código:
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-5A5C126069B253F2B0135998798458616" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
MIIEpDCCBA2gAwIBAgIEPLPTKTANBgkqhkiG9w0BAQUFADA2MQswCQYDVQQGEwJFUzENMAsGA1UEChMERk5NVDEYMBYGA1UECxMPRk5NVCBDbGFzZSAyIENBMB4XDTALS6PmAJWFoOUT3Xvp8UxYptb9/YK93ykPj5NYLcsXeh8L9SRWbFSnozoiATZoECDnrcMd054DdPrNVYLTZNhZ9Y2U9JqJpnIWR+a64Mo3iiMk/KBkI2jo3QIuaCjvPK+k6LQCwTIaRvnHGRxwIDAQABo4IB1DCCAdAwgdgGA1UdEQSB0DCBzaSByjCBxzEYMBYGCSsGAQQBrGYBDxMJUzI4MjYwMTVGMUMwQQYJKwYBBAGsZgEOEzRJTlRFUlZFVc9fS1I6qgUkmwCZKHiwgJ4tS1Mv3gKMZ+8ulc8JErYo661ql3GVmLsfdH5g3eWyC5rBEcCjkHSKO0qDhzg==

</wsse:BinarySecurityToken>

<ds:Signature Id="Signature-11" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethodAlgorithm="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-12">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>vfoQe7yobzrB5LzQZ/HD4B2F1BY=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
HOZFzxAsMAH8BDbuXOHekl+yyLXfodmPka5727t3LDFSkbxICkL92wy6dSbWyU07zK/dhfLl2a4c
33FcvOxAtYAEvQVRLcQM3VU9+L2SX9NReQaGTPPmtBb8UAWeH5m56nM9uxT7yIwfO424+lNEYEeo
1pYC+0DBI6WcN4LRgV4=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-5A5C126069B253F2B0135998798458717">
<wsse:SecurityTokenReference wsu:Id="STRId-5A5C126069B253F2B0135998798458718"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:ReferenceURI="#CertId-5A5C126069B253F2B0135998798458616"
ValueType="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="Timestamp-10" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2013-02-04T14:26:24.586Z</wsu:Created>
<wsu:Expires>2013-02-04T14:31:24.586Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
Los componentes de SecureBlackBox permiten firmar peticiones SOAP usando certificados de diferentes tipos, y añaden la sección security al header, PERO no de la misma forma que en este ejemplo. Además, estaría bien saber si es posible hacerlo sin dichos componentes, ya que hay muchos usuarios que no los utilizan.
Responder Con Cita
  #25  
Antiguo 04-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 143
Poder: 15
iMia Va por buen camino
Bien!!
bueno, varias cosas.... yo no utilizo SBB... Además, no estoy programando nada sobre el Face, aún... me pondré más adelante... simplemente te intentaba ayudar un poco...

En el tema de la cabecera, el código que pones yo lo haría diferente... simple cuestión de estilo...

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var 
    facturasspp : SSPPFactura;
    fichero_fac : SSPPFicheroFactura;
    answ : SSPPResultadoEnviarFactura;


    htpr: THTTPRIO;
    sphdr: TSOAPHEADER;
    WS: SSPPWebServiceProxyPort;
begin
    if opendialog1.Execute then
    begin
        //Creamos los headers, necesarios para la petición SOAP
        sphdr := TSOAPHEADER.create;

        // Creo el HTTP, que utilizaré como vehiculo, así no tengo que hacer Typecasts que no me gustan nada...
        htpr := THTTPRIO.create(Self);

        //Aquí trabajamos con el propio httprio, donde podemos poner cabeceras, asignar eventos, etc...

        htpr.SOAPHeaders.Send(sphdr);
        // htpr.OnBeforeExecute := BeforeExecuteHttpRio(...
        // htpr.OnAfterExecute := AfterExecuteHttpRio(...

        // Al crear la instancia del WS, le asigno el httprio que he creado y he manipulado...

        WS:= GetSSPPWebServiceProxyPort(FALSE, '', htpr);

        facturasspp := ssppfactura.Create;
        facturasspp.correo := 'prueba@miemail.com';
        fichero_fac := ssppficherofactura.Create;
        fichero_fac.nombre := extractfilename(opendialog1.FileName);
        fichero_fac.factura := '72345';
        fichero_fac.mime := 'application/xml';
        facturasspp.fichero_factura := fichero_fac;

        try
            // Me cargo el typecast... que para eso se ha instanciado el ws sobre la variable WS
            answ := WS.enviarFactura(facturasspp);
        except
            on e:exception do showmessage(e.Message);
        end;
    end;

end;

el tema de utilizar un TxmlDocuemnt, es simplemente para ponerlo de ejemplo, para firmarlo y re-inyectarlo en la cabecera.
Se puede hacer como quieras...

El tema de lo que debe ir en el header... ese ya es otro tema que habría que aclarar...

Si con SBB te permite firmar llamadas SOAP, esta claro que debe ir en el header... capturar la llamada, firmarla, inyectarla en el header y seguir enviando la llamada original, con la llamada firmada en el header... (donde pone "security content")...
Responder Con Cita
  #26  
Antiguo 04-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Bueno...

Estoy viendo las demos de SecureBlackBox, que permiten añadir la firma al header del soap, pero tienen varias opciones y compatibilidad con varios certificados, así que habrá que averiguar cual hay que elegir.
Estas capturas de pantalla son de la aplicación demo que se incluye en los SecureBlackBox.
La aplicación nos permite abrir un XML y, entre otras cosas, añadir una firma, verificarla, quitarla, o actualizarla, y volver a guardar el XML resultante ya firmado.

Lo primero que nos pregunta es el Signature Handler. 3 opciones. Yo he elegido la WSS Signature Handler, que no sé si es la correcta porque NO ME ENTERO DE NADA:
1.png

En esa misma ventana nos pregunta si queremos crear la cabecera, o sustituir una ya existente. Como nuestro XML no tiene cabecera, le decimos que la cree.
Además, hay otra opción "sign body" que no sé qué hace. Tendré que hacer pruebas diferentes y comparar un resultado con otro para entenderlo mejor.

El siguiente paso es elegir el certificado con el que queremos firmar el XML, el Key Name, etc. y aquí tenemos otras opciones que debemos elegir de una lista: Embed Certificate Option, que supongo que es la forma en la que se incrusta el certificado:
2.png

Como tampoco tengo ni idea, pues tendré que hacer pruebas y rezar para que alguna de ellas funcione.

Una vez hemos añadido la firma y el securiyu header al XML, la sección HEADER de nuestro XML quedará así (más o menos)

Código:
<SOAP-ENV:Header SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:Soap.InvokeRegistry">
<NS1:TSOAPHeader xsi:type="NS1:TSOAPHeader"/>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="id-278627682" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">MIIIkTCCB3mgAwIBAgIJAK2....................................</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<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-1455977767">
<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>pyHVuQqgYvQ3F1PIb+Cw39jfq2M=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo><ds:SignatureValue>kDLUYUxnRCmiR6TPwBAg/..................................</ds:SignatureValue><ds:KeyInfo><ds:KeyValue><ds:RSAKeyValue>
<ds:Modulus>AIHDAKJSAS.....................................................</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue></ds:KeyValue>
<wsse:SecurityTokenReference wsu:Id="" TokenType="" Usage="" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Reference URI="#id-278627682" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference><ds:X509Data><ds:X509Certificate>MIIIkTCCB3mgAw...................</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</SOAP-ENV:Header>
Esto se parece más al header del XML que aparece en la documentación del face, aunque no es exacto (hay muchas más cosas).

Durante estos días intentaré probar todas las opciones y averiguar si es posible crear el tipo de firma que exige face.
Responder Con Cita
  #27  
Antiguo 04-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 143
Poder: 15
iMia Va por buen camino
Tal uy como te puse por privado, según el manual de los servicios Web....

Las peticiones tanto como las respuestas deben ir firmadas según el estandar OASIS WSSecurity 1.0 X509 Token Profile
http://en.wikipedia.org/wiki/WS-Security
http://docs.oasis-open.org/wss/2004/...rofile-1.0.pdf
La plataforma FACe delega sobre la plataforma @firma
(http://administracionelectronica.gob.es/ctt/afirma) la validación y la firma electrónica
digital de los servicios web, por lo que usted puede encontrar la documentación completa
en la misma.
Responder Con Cita
  #28  
Antiguo 04-11-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.549
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Aunque no estoy interviniendo actívamente porque ahora no estoy con este tema, agradeceros (al menos a nivel personal) toda la información detallada que estáis adjuntando en este hilo.

Creo que antes o después nos será útil a michos de nosotros.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #29  
Antiguo 04-11-2015
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.591
Poder: 21
newtron Va camino a la fama
Cita:
Empezado por Neftali Ver Mensaje
Aunque no estoy interviniendo actívamente porque ahora no estoy con este tema, agradeceros (al menos a nivel personal) toda la información detallada que estáis adjuntando en este hilo.

Creo que antes o después nos será útil a michos de nosotros.
Totalmente de acuerdo.
__________________
Be water my friend.
Responder Con Cita
  #30  
Antiguo 04-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Esta mañana he conseguido averiguar qué tipo de firma usar, y comparando los resultados con el de la dlcumentacion, creo que es la correcta.

Hasta mañana no podré seguir probando, pero en cuanto avance algo más lo iré publicando.

Eso sí, habrá que hacerlo con los SecureBlackBox. Al menos yo no sé si habrá otro método...
Responder Con Cita
  #31  
Antiguo 05-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Bueno, creo que lo he conseguido

Aquí pongo una captura de pantalla de la respuesta que me da el webservice después de crear la petición soap, firmarla y enviar una factura:
4.jpg

Voy a limpiar un poco el código, añadir comentarios y hacer pruebas con un certificado ya dado de alta en el webservice para comprobar que funciona correctamente, e iré publicando los pasos poco a poco.

Lo que he hecho es lo siguiente. A partir de un proyecto de ejemplo suministrado por los componentes SecureBlackBox, que permite firmar peticiones SOAP (que es lo que nos faltaba), lo he ido adaptando y simplificando para que, a partir de la factura electrónica que creamos en el primer post, añada la firma, cabeceras, etc. requeridas por el webservice.

Hay que hacer dos firmas: la primera, para crear la factura electrónica (primer post), y la segunda para firmar la petición soap. Para ambas firmas usaríamos el mismo certificado. Los componentes SecureBlackBox permiten usar cualquier tipo de certificado (a partir de un .p12, .cer, de los certificados instalados en Windows, etc.).

No he conseguido hacerlo sin los componentes SecureBlackBox, lo siento. Supongo que es posible usar un certificado del almacén de certificados de Windows con código puro y duro, pero no he tenido tiempo de averiguar eso. Además, habría que incrustar al SOAP las cabeceras y toda la información del certificado a mano, y aunque es posible, lo veo una locura. Los SecureBlackBox lo hacen automáticamente.

Intentaré publicar los pasos esta tarde o mañana.
Responder Con Cita
  #32  
Antiguo 11-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Sigo vivo. Llevo esperando una semana respuesta desde face, porque el webservice me devuelve el siguiente error:

100 - La firma de la petición soap no es válida

Así que a esperar.
Responder Con Cita
  #33  
Antiguo 11-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 143
Poder: 15
iMia Va por buen camino
Cita:
Empezado por espinete Ver Mensaje
Bueno, creo que lo he conseguido

No he conseguido hacerlo sin los componentes SecureBlackBox, lo siento. Supongo que es posible usar un certificado del almacén de certificados de Windows con código puro y duro, pero no he tenido tiempo de averiguar eso. Además, habría que incrustar al SOAP las cabeceras y toda la información del certificado a mano, y aunque es posible, lo veo una locura. Los SecureBlackBox lo hacen automáticamente.

Intentaré publicar los pasos esta tarde o mañana.
Ni lo conseguirás... por desgracia... no hay ninguna librería que firme y que sea free en Delphi...
Responder Con Cita
  #34  
Antiguo 19-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Me he quedado atascado, y la única respuesta que me dan los de soporte del webservice es la misma respuesta que me da el validador online de firma (https://valide.redsara.es/valide/inicio.html):

"Id is not an attribute"

Así que ni idea.

Estoy hablando con el soporte de Eldos, creadores de los SecureBlackBox, a ver si me ayudan a ver qué pasa. Me niego a dejar esto ahora ya que creo que tengo el 90% conseguido, pero la verdad es que hay días que me dan ganas de abandonar y esperar a que pase algo más de tiempo para que haya más información en la red.

Seguiré intentándolo
Responder Con Cita
  #35  
Antiguo 27-11-2015
elguille elguille is offline
Miembro
 
Registrado: ene 2005
Posts: 114
Poder: 20
elguille Va por buen camino
Hola Espinete, despues de mucho tiempo voy a retomar este tema. Cuando lo deje estaba atascado con el error "connection lost" ahora no me da error pero el servicio retorna

<faultcode>500</faultcode>
<faultstring>20151127135337151899 - 300 - El certificado electr&#xF3;nico no est&#xE1; dado de alta en FACe. Para la presentaci&#xF3;n automatizada de facturas es necesario registrarse previamente en https://face.gob.es/es/proveedores</faultstring>

me fijo que he empleado el servicio definido en

https://webservice.face.gob.es/sspp

el cual segun la nueva documentacion es antiguo (aunque esta activo )

si empleo los nuevos, recibo diferentes errores para la misma peticion soap que antes (que no da error)

STAGING (https://se-face-webservice.redsara.es/facturasspp2) RCP-Literal
Decode from base64 failed

PROD (https://webservice.face.gob.es/facturasspp2) RCP-Literal
Xml parse error at position 1 (0x1)

¿Alguna idea? Gracias

Este el el codigo
Código Delphi [-]
// pruebas con cliente secureblackboc
              FXMLDocument := TElXMLDOMDocument.Create;
              FXMLDocument.LoadFromFile(extractfilepath(application.exename) + 'requestsoap.xml');
              FSOAPClient := TElXMLSOAPClient.Create(nil);
              try
                FSOAPClient.SOAPPrefix := 'soap';
                FSOAPClient.SOAPVersion := SOAP_v1_2;
                FSOAPClient.OperationName := 'enviarFactura';

                FSOAPClient.MessageNamespaces.Clear;
                FSOAPClient.HTTPClient := HTTPSClient;
// entorno pruebas que no funciona
//                FSOAPClient.URL := 'https://se-face-webservice.redsara.es/facturasspp';
// produccion
                FSOAPClient.URL := 'https://webservice.face.gob.es/facturassspp2';
                FSOAPClient.OperationNamespaceURI := 'https://webservice.face.gob.es';
                FSOAPClient.SOAPAction := 'https://webservice.face.gob.es#enviarFactura';

                fsoapclient.GenerateMessage;
                FSOAPClient.XMLDocument.LoadFromFile(extractfilepath(application.exename) + 'requestsoap.xml');
                FSOAPClient.SOAPMessage.LoadFromXML(FSOAPClient.XMLDocument); // reload a SOAP message if needed

                FSOAPClient.SendMessage;
                fsoapclient.ResponseXMLDocument.SaveToFile('resul.xml');

              except
                on E: Exception do
                begin
                  MessageDlg('Failed to send SOAP message: ' + E.Message, mtError, [mbOk], 0);
                end;
              end;
Responder Con Cita
  #36  
Antiguo 01-12-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Hola, elguille

Lo siento, yo no uso el componente TElXMLSOAPClient. Sólo uso los componentes de SecureBlackBox necesarios para hacer las firmas.
Para enviar la petición SOAP, importo el wsdl y hago la petición tal como indiqué en un post anterior.

Los técnicos de SecureBlackBox están intentando ayudarme a crear/firmar la petición SOAP, pero siempre obtengo "La firma de la petición soap no es válida".

Si existiera UN SOLO EJEMPLO de una petición soap completa para poder comparar sería todo maravilloso, pero en las instrucciones solo hay peticiones sin firmar.
Responder Con Cita
  #37  
Antiguo 01-12-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Hola de nuevo.

He hecho una mezcla entre mi código y el de elguille, y he usado el webservice nuevo de STAGING para pruebas. PARECE QUE FUNCIONA, pero obtengo un error:

411 - No existe o inactiva la Oficina Contable asociado al código "A05003410"

He usado una oficina contable, unidad tramitadora, etc. al azar. ¿Alguien sabe si puede usarse cualquiera en el entorno de pruebas? ¿O es que he tenido mala suerte y esa no vale?

Al menos ya no obtengo el error 100 (La firma de la petición soap no es válida) ni ningún otro error!!!!
Responder Con Cita
  #38  
Antiguo 01-12-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Thumbs up

Bueno, creo que funciona

He conseguido obtener el listado de Administraciones, que también requiere una petición soap firmada. No puedo enviar captura de pantalla porque los límites de tamaño y dimensiones para los archivos son un tanto peculiares en el foro...

Mañana intentaré enviar una factura (necesitaría saber qué código de administración es válido) y poner el código que he usado
Responder Con Cita
  #39  
Antiguo 10-12-2015
elguille elguille is offline
Miembro
 
Registrado: ene 2005
Posts: 114
Poder: 20
elguille Va por buen camino
Espinete, ¿lo has conseguido? ¿Puedes ilustrarnos?

Gracias
Responder Con Cita
  #40  
Antiguo 10-12-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 286
Poder: 16
espinete Va camino a la fama
Hola!

Pues sí, creo que lo tengo todo, a falta de probar en modo producción.
Esta semana ha habido varios cortes del servicio (avisan por email cuando tienen previsto uno), pero conseguí hacer pruebas para enviar una factura, consultar el estado de una factura, obtener el listado de organismos disponibles, anular una factura, etc.

Mañana intentaré poner algunos ejemplos, pero ahora mismo tengo este a mano: Consultar Administraciones:

Código Delphi [-]
procedure TfrmMain.Button3Click(Sender: TObject);
var
    answ : ConsultarAdministracionesResponse;
    htpr: THTTPRIO;
    sphdr: TSOAPHEADER;
    WS: FacturaSSPPWebServiceProxyPort;
    UnidadDir : UnidadDir3;
    i:integer;
begin
    if comboCertificate.ItemIndex=-1 then
    begin
      showmessage('Debe seleccionar primero un certificado en el desplegable.');
      exit;
    end;
    
    Listbox1.items.clear;

        //Creamos los headers, necesarios para la petición SOAP
        sphdr := TSOAPHEADER.create;

        // Creo el HTTP, que utilizaré como vehículo
        htpr := THTTPRIO.create(Self);

        //Aquí trabajamos con el propio httprio, donde podemos poner cabeceras, asignar eventos, etc...

        htpr.SOAPHeaders.Send(sphdr);
        htpr.OnBeforeExecute := HTTPRIO1BeforeExecute;

        // Al crear la instancia del WS, le asigno el httprio que he creado y he manipulado...
        WS:= GetFacturaSSPPWebServiceProxyPort(FALSE, '', htpr);
        try
            answ := WS.consultarAdministraciones;
        except
            on e:exception do showmessage(e.Message);
        end;

        if answ.resultado.codigo='0' then
        begin
            UnidadDir := UnidadDir3.Create;
            for i:=0 to length(answ.administraciones)-1 do
            begin
                UnidadDir := answ.administraciones[i];
                begin
                    listbox1.items.append(UnidadDir.codigo + ' - ' + UnidadDir.nombre )
                end;
            end;
            UnidadDir.Free;
        end;
end;

El evento HTTPRIO1BeforeExecute creo recordar que ya lo publiqué en otro post más arriba.
Cuando tenga más tiempo editaré el post original añadiendo todas las funciones.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Facturas Electronicas Argentina Chaja Varios 3 10-07-2015 20:15:05
Agregar Adendas a Facturas electronicas mexico reypcs Varios 0 20-01-2011 17:26:10
Tabla de Facturas vs Detalles de Facturas magnu9 Conexión con bases de datos 9 27-07-2007 18:27:37
Comunicaciones electronicas EDI Toni Conexión con bases de datos 0 18-04-2006 14:06:34
Campos calculados, facturas y detalles de facturas. Letty Conexión con bases de datos 7 07-11-2003 12:19:44


La franja horaria es GMT +2. Ahora son las 02:10:51.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi