lunes, 4 de noviembre de 2019

Crear Wallet en Base de Datos Oracle: UTL_HTTP y SSL

Si estás tratando de consumir un servicio Web por medio de HTTPS a nivel de código PL/SQL o por otra vía en la Base de Datos y te da el siguiente error:

ORA-29024: Certificate validation failure

Es debido a que la base de datos no confía en el certificado digital que se le presenta cuando trata de establecer comunicación con el servidor donde se encuentra alojado el servicio web en cuestión.

Para solucionar ésto lo que debemos hacer es conseguir el certificado del servidor donde se encuentra alojado el servicio web y crear una Wallet a nivel del sistema operativo donde se encuentra instalada nuestra base de datos. El certificado se puede conseguir en la barra de dirección del navegador cuando ponemos el WSDL del servicio.

Una vez tenemos el certificado realizamos los siguientes pasos:

1. Crear carpeta que contendrá el wallet:

mkdir -p /u01/app/oracle/wallet

2. Configurar las variables de ambiente de la base de datos porque haremos uso de la utilidad de orapki

3. Crear wallet:

orapki wallet create -wallet /u01/app/wallet -pwd welcome123 -auto_login

4. Agregar certificado:

orapki wallet add -wallet /u01/app/oracle/wallet -trusted_cert -cert "/u01/Root.crt" -pwd welcome123

5. Probar la invocación del servicio, para ello agregar el wallet antes de la invocación del servicio:

En mi caso lo probaré desde el SQLPLUS, una sola sesión todo lo siguiente:

SET SERVEROUTPUT ON
EXEC UTL_HTTP.set_wallet('file:/u01/app/oracle/wallet', NULL);
Creamos el siguiente procedimiento almacenado:

CREATE OR REPLACE PROCEDURE show_html_from_url (
  p_url  IN  VARCHAR2,
  p_username IN VARCHAR2 DEFAULT NULL,
  p_password IN VARCHAR2 DEFAULT NULL
) AS
  l_http_request   UTL_HTTP.req;
  l_http_response  UTL_HTTP.resp;
  l_text           VARCHAR2(32767);
BEGIN
  -- Make a HTTP request and get the response.
  l_http_request  := UTL_HTTP.begin_request(p_url);

  -- Use basic authentication if required.
  IF p_username IS NOT NULL and p_password IS NOT NULL THEN
    UTL_HTTP.set_authentication(l_http_request, p_username, p_password);
  END IF;

  l_http_response := UTL_HTTP.get_response(l_http_request);

  -- Loop through the response.
  BEGIN
    LOOP
      UTL_HTTP.read_text(l_http_response, l_text, 32766);
      DBMS_OUTPUT.put_line (l_text);
    END LOOP;
  EXCEPTION
    WHEN UTL_HTTP.end_of_body THEN
      UTL_HTTP.end_response(l_http_response);
  END;
EXCEPTION
  WHEN OTHERS THEN
    UTL_HTTP.end_response(l_http_response);
    RAISE;
END show_html_from_url;
/
Por último probamos la invocación:

EXEC show_html_from_url('https://esb.rinnovo.com:8885/purchase/get-transactions');
Obtendremos la respuesta de nuestro servicio sin problemas:

SQL> EXEC show_html_from_url('https://esb.rinnovo.com:8885/purchase/get-transactions');
{"generalResponse":{"responseDescription":"Version no
especificada","errors":[{"code":"400","id":"4b157gda-a7fc
","detail":"No se especificado un encabezado URI
existente","title":"Version no especificada"}],"responseCode":"700"}}

PL/SQL procedure successfully completed.

SQL>

Con el procedimiento anterior, solo bastará agregar la linea donde configuramos el Wallet sin el EXEC.