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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 233
Poder: 16
espinete Va camino a la fama
Pues no lo sé, pero ya bastante tengo con que no lo consiga hacer desde Windows. Supongo que habilitarán más protocolos en el futuro.
Responder Con Cita
  #2  
Antiguo 02-11-2015
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por espinete Ver Mensaje
.... Supongo que habilitarán más protocolos en el futuro.
Responder Con Cita
  #3  
Antiguo 02-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 141
Poder: 14
iMia Va por buen camino
SOAP (Simple Object Access Protocol) no es exclusivo de windows... es un protocolo de comunicaciones, para el intercambio de información... Inicialmente en xml...

Espinete... seguramente el problema lo tienes que al importar el WSDL, hay que hacer un cambio por que el server Tomcat, requiere SOAP 1.1 y no 1.2...
¿donde? os preguntareis...

Al registrar las opciones de invocación, hay que cambiar el TypeInfo, del tipo ioDocument por ioDefault
con eso queda arreglado...

Código:
//  InvRegistry.RegisterInvokeOptions(TypeInfo(xxxx), ioDocument);
  InvRegistry.RegisterInvokeOptions(TypeInfo(xxxx), ioDefault);

Saludos
Responder Con Cita
  #4  
Antiguo 03-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 233
Poder: 16
espinete Va camino a la fama
Hola, iMia...

Gracias por tu aportación... pero tras importar el WSDL, en la unit resultante (sspp.pas), no hay ninguna referencia a InvRegistry.RegisterInvokeOptions(), por lo que no puedo sustituirlo (Delphi XE7 y Delphi Seattle).

Lo más parecido está en la parte initialization de esa unit:

Código Delphi [-]
initialization
  { SSPPWebServiceProxyPort }
  InvRegistry.RegisterInterface(TypeInfo(SSPPWebServiceProxyPort), 'https://webservice.face.gob.es', 'UTF-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(SSPPWebServiceProxyPort), 'https://webservice.face.gob.es#%operationName%');
  {...}
  {...}

¿Dónde exactamente debo hacer el cambio que sugieres?
Responder Con Cita
  #5  
Antiguo 03-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 141
Poder: 14
iMia Va por buen camino
Si correcto, lo acabo de importar para verlo...
y no aparece esa linea....
prueba de añadirla tal que...

Código:
 InvRegistry.RegisterInvokeOptions(TypeInfo(SSPPWebServiceProxyPort), ioDefault);
justo debajo de las dos que muestras...

Saludos...

Yo tambien en XE7...
Responder Con Cita
  #6  
Antiguo 03-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 233
Poder: 16
espinete Va camino a la fama
Hecho.

Pero sigue igual:

La petición SOAP no está bien construida: no se encuentra el SOAP Header.
Imágenes Adjuntas
Tipo de Archivo: png Sin título.png (3,1 KB, 23 visitas)
Responder Con Cita
  #7  
Antiguo 03-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 141
Poder: 14
iMia Va por buen camino
Uffff...

Voy a probar..
pero al importar el wsdl, el codigo me da un error...
En la funcion "consultarListadoFacturas" el parámetro pone que es de tipo Array... pero no de que es ese array...

Código:
function consultarListadoFacturas(const listadoFacturas: Array): ArrayOfSSPPResultadoConsultarFactura; stdcall;
¿como lo has arreglado tu?
Responder Con Cita
  #8  
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.000
Poder: 25
Ñ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
  #9  
Antiguo 04-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 141
Poder: 14
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
  #10  
Antiguo 04-11-2015
espinete espinete is offline
Miembro
 
Registrado: mar 2009
Posts: 233
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
  #11  
Antiguo 04-11-2015
iMia iMia is offline
Miembro
 
Registrado: jul 2010
Posts: 141
Poder: 14
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
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 19:15:05
Agregar Adendas a Facturas electronicas mexico reypcs Varios 0 20-01-2011 16:26:10
Tabla de Facturas vs Detalles de Facturas magnu9 Conexión con bases de datos 9 27-07-2007 17:27:37
Comunicaciones electronicas EDI Toni Conexión con bases de datos 0 18-04-2006 13:06:34
Campos calculados, facturas y detalles de facturas. Letty Conexión con bases de datos 7 07-11-2003 11:19:44


La franja horaria es GMT +2. Ahora son las 19:29:50.


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