xmlhttprequest autenticacion por certificado


([N1] anton) #1

Buen día a todos,

He estado probando el utilizar webservices que requieren autenticación mediante certificados digitales, como en el caso de la AEAT para el suministro de información inmediata.

Sin embargo no encuentro la manera de hacerlo con la implementación actual de XMLHTTPREQUEST, si, ya sé que se puede mediante curl (hay un ejemplo funcional en el foro), pero me interesa hacerlo mediante dicha clase.

Revisando en distintos foros nadie encuentra la manera de hacerlo desde aplicaciones de escritorio, siempre desde navegador y registrando el correspondiente certificado en su correspondiente almacén.

Pero resulta que me encontré la siguiente página, en donde hacen una implementación de un método que resuelve dicho problema. https://wakanda.github.io/wakanda-api-reference/docs/interfaces/xmlhttprequest.html#setclientcertificate Anexo tambien imagen del método.

Mi pregunta es, ¿será posible que en la siguiente versión de V7 se implemente algo parecido?, toda vez que aparentemente existe una tendencia a autenticarse a consumo de WebServices mediante esta técnica y la verdad estoy encantado con el uso de XMLHTTPREQUEST actualmente.

O si alquien conoce alguna manera de hacerlo y me pudiera orientar al respecto.

Gracias por sus comentarios.

Anton.


([N1] anton) #2

Va la imagen, que no subio en el primer post.



([N4] innovadb) #3

Hola Anton

Yo me encontré el mismo problema y después de tres días no fui capaz de solucionarlo desde v7.

Al final la mejor opción que encontré fue hacer la conexión y el envío con python y dejar en un fichero de texto todos los datos necesarios para recogerlos desde v7.

Un saludo


([N4] Infortic) #4

Yo tampoco lo he conseguido para https autofirmado, la respuesta de soporte fue que no se soporta y no parece que se vaya a soportar.

Tuve que usar curl finalmente.


([N1] anton) #5

Gracias innovadb e Infortic, una pena que no implementen esa funcionalidad en futuras versiones (en caso que no lo hayan planeado), toda vez que existen otras implementaciones de dicha clase que si lo hacen, tales como la mencionada de WAKANDA, el WinHttpRequest, y tantas otras en Java.

Desconozco qué tan fácil o difícil resulte ser eso, pero de que hace falta, hace falta.

Solo aclarar, la clase actual del API de velneo SI puede trabajar con sitios https (yo lo hago sin ningún problema), siempre y cuando o no soliciten contraseña o la manejen “normal”, enviando un nombre de usuario y clave o generando un token de algún modo, solo no se puede usar cuando el sitio requiere autenticación por certificado digital, como en el caso de la AEAT.

Saludos.


([N4] Infortic) #6

Es cierto, en mi caso era autofirmado, por lo que aparece como no seguro y no te deja


([N1] leonardo daniel velazquez fuentes) #7

Hola… olvidate de XMLHttpRequest… es una mala broma… la documentacion de risa… y el ejemplo que me mando soporte ( ejemplo externo, no me sirvio de nada ) a fin de cuentas se decidio crear una tabla con las ciudades destino de los viajes asi como sus millas (ya que no son tantas), tanto de ida como de vuelta por no siempre es el mismo camino de regreso y se ahorro el gasto de pagarla a la empresa que daba el WebService de trazado de rutas de Camiones de carga pesada…


([N1] anton) #8

Hola Leonardo,

No entiendo a qué te refieres con que XMLHTTPREQUEST es una mala broma, en lo particular llevo poco utilizándolo y me ha resuelto sin ningún problema la conexión a todos los webservices que he necesitado, con excepción de los que requieren autenticación por certificado digital, lo utilizo para timbrar facturas en México con múltiples PACs, y a pesar de que cada PAC se pone sus moños, pues una vez analizando sus peticiones y sus responses no me queda más que ir parseando los resultados y sin problema alguno.

Quizás no he tenido necesidades más complejas, pero pues simple, si no me funciona uso CURL o pyton o cualquier otra.

Saludos.

Anton.


([N1] anton) #9

¡Pues lo pusieron!

A probarlo se a dicho.


([N4] eduarchap) #10

Saludos Anton

En efecto yo tampoco pude lograrlo, lo solucione con PHP directamente.

Por cierto anton, para los webservice que trabajan con SOAP. como lo has resuelto?

Saludos.


([N4] Infortic) #11

Hola

En el body si le pones el envelope soap funciona sin problemas.

Yo he implementado ws de UPS, DHL, FEDEX, etc… con xmlhttprequest, con envelope SOAP y no ha habido problemas.


([N4] eduarchap) #12

Saludos infortic

Ah genial, algo asi me imaginaba pero no lo habia probado… Ahora para el tema del certificado si no hay solucion cierto?

Otra consulta, sabes que existen algunos WebServices que requieren del UpLoad de un archivo de disco (seagun sea el caso) si lo veo en PHP seria algo como

@.$RUTA_ARCHIVO

Pero en este caso lo has hecho con el JS de V7?

Saludos.


([N1] anton) #13

Hola eduarchap, como comenta Infortic, en el body lo defines y va bien, me hacia falta el tema que acaban de poner, autenticación por certificado, lo de enviar archivos todavía no lo he hecho pero no tardaré en hacerlo, te comento.
Saludos.

Anton.


([N3] pacosatu) #14

Hola.

Si queréis comprobar la nueva función setClientCertificate() de la clase XmlHttprequest lo podéis hacer con el siguiente código que consulta el saldo de Puntos de la Dirección General de Tráfico.
Es una petición GET pero es lo mismo para las peticiones POST.

importClass("VFile")
importClass("XMLHttpRequest")
var xhr = new XMLHttpRequest()

// Consulta de puntos en Tráfico
xhr.open("GET", "https://sedeapl.dgt.gob.es:9443/WEB_COPACI3/certificado/verSaldoPuntosCert.faces", false)
// Para los que no tengáis carnet de conducir probad con el Test del CNMC
// xhr.open("GET", "https://api.cnmc.gob.es/test/v1/echoseguro/Test de certificado", false)

// Obtenemos los strings con el Certificado y la Clave privada disponibles en formato PEM
var oFichero_Certificado = new VFile( "D:\\certificados\\certificado_solo.pem" );
var cCertificado_Solo = "";
if ( oFichero_Certificado.open( VFile.OpenModeReadOnly ) )
    cCertificado_Solo = oFichero_Certificado.readAll().toLatin1String();    
var oFichero_ClavePrivada = new VFile( "D:\\certificados\\certificado_clave_privada.pem" );
var cCertificado_ClavePrivada = "";
if ( oFichero_ClavePrivada.open( VFile.OpenModeReadOnly ) )
    cCertificado_ClavePrivada = oFichero_ClavePrivada.readAll().toLatin1String();    

// Especificamos el Certificado y la Clave privada para el acceso seguro SSL indicando la identidad del Cliente
if (cCertificado_Solo && cCertificado_ClavePrivada) {
	xhr.setClientCertificate(cCertificado_Solo, cCertificado_ClavePrivada, "password_clave_privada");
}
// Enviamos el Request
xhr.send()

if (parseInt(xhr.status) == 200) {
	alert (xhr.responseText)
}
else {
	alert ("<code>Error: " + xhr.responseText + "</code>")
}

En España podéis usar el certificado personal de la FNMT exportado como .pfx desde vuestra lista de certificados del explorador web.
La conversión a PEM se realiza con la herramienta openssl (necesitamos tener instalado OpenSSL). Ver también las opciones del comando openssl pkcs12.

El certificado debe dividirse en 2 ficheros:

  • El certificado en sí mismo
    C:\OpenSSL-Win32\bin\openssl pkcs12 -in MiCertificado_FNMT.pfx -out certificado_solo.pem -clcerts -nokeys
  • y la clave privada
    Debemos especificar una password para la clave privada (3º parámetro de setClientCertificate() de Velneo)
    C:\OpenSSL-Win32\bin\openssl pkcs12 -in MiCertificado_FNMT.pfx -out certificado_clave_privada.pem -nocerts
    Con la opción -nodes NO hace falta la password de la clave privada
    C:\OpenSSL-Win32\bin\openssl pkcs12 -in MiCertificado_FNMT.pfx -out certificado_clave_privada.pem -nocerts -nodes

Saludos
Paco Satué


([N1] anton) #15

Como siempre muchas gracias Paco Satué, más sencillo no se puede.

Saludos.

Anton.