如何使用UTL_HTTP包在pl / sql过程中调用HTTPS Api?

How to call HTTPS Api in pl/sql procedure using UTL_HTTP package?

提问人:amila upendra 提问时间:11/17/2023 最后编辑:MT0amila upendra 更新时间:11/17/2023 访问量:27

问:

我在尝试使用 UTL_HTTP 包从 PL/SQL 过程调用 HTTPS API 服务时遇到了挑战。我已经成功调用了 HTTP 服务,但在 HTTPS 调用方面遇到了困难。

精通此过程的人能否指导我完成使用 PL/SQL 和 UTL_HTTP 安全调用 HTTPS API 服务的必要步骤?我非常感激说明如何在 PL/SQL 过程中成功处理 HTTPS 请求的见解或示例,包括任何特定配置或潜在的故障排除步骤,以确保 HTTPS 调用按预期工作。

这是我的pl / sql代码

CREATE OR REPLACE PROCEDURE call_api (
  p_name IN VARCHAR2,
  p_age IN NUMBER
) IS
  req utl_http.req;
  res utl_http.resp;
  url VARCHAR2(4000) := 'https://qh5rz7xna7.execute-api.ap-south-1.amazonaws.com/sample';
  buffer VARCHAR2(4000);
  content VARCHAR2(4000) := '{"name":"' || p_name || '","age":' || p_age || '}';
BEGIN
  req := utl_http.begin_request(url, 'POST', 'HTTP/1.1');
  utl_http.set_header(req, 'user-agent', 'mozilla/4.0'); 
  utl_http.set_header(req, 'content-type', 'application/json'); 
  utl_http.set_header(req, 'Content-Length', LENGTH(content));
 
  utl_http.write_text(req, content);
  res := utl_http.get_response(req);

  -- Process the response from the HTTP call
  BEGIN
    LOOP
      utl_http.read_line(res, buffer);
      dbms_output.put_line(buffer);
    END LOOP;
    utl_http.end_response(res);
  EXCEPTION
    WHEN utl_http.end_of_body THEN
      utl_http.end_response(res);
  END;
END call_api;
/


SET SERVEROUTPUT ON;

BEGIN
  call_api('john', 20);
END;

这是创建的 ACL

BEGIN
  DBMS_NETWORK_ACL_ADMIN.create_acl (
    acl          => 'local_sx_acl_file.xml', 
    description  => 'A test of the ACL functionality',
    principal    => 'AMILA',
    is_grant     => TRUE, 
    privilege    => 'connect',
    start_date   => SYSTIMESTAMP,
    end_date     => NULL);
end;
 
begin
  DBMS_NETWORK_ACL_ADMIN.assign_acl (
    acl         => 'local_sx_acl_file.xml',
    host        => '*', 
    lower_port  => NULL,
    upper_port  => NULL);    
end; 
Oracle PLSQL的

评论


答:

1赞 d r 11/22/2023 #1

最近遇到了一些问题。不确定这是否对您有所帮助,但以下是我为使其正常工作所做的工作:

  1. 为钱包创建了新文件夹(类似于:C:\some_dir\wallets)
  • 为调用 API 的用户提供完全控制权限(文件夹属性 - 安全选项卡)enter image description here
  1. 添加到 .ora 文件中的钱包位置和身份验证的定义
#listener.ora
SSL_CLIENT_AUTHENTICATION = FALSE
WALLET_LOCATION =
  (SOURCE =
    (METHOD = FILE)
    (METHOD_DATA =
      (DIRECTORY = your_wallet_folder_path)
    )
  )
-------------------------------------------------------------------------------------------  
#tnsnames.ora
WALLET_LOCATION =
   (SOURCE =
     (METHOD = FILE)
     (METHOD_DATA =
       (DIRECTORY = your_wallet_folder_path)
     )
   )
------------------------------------------------------------------------------------------ 
#sqlnet.ora
WALLET_LOCATION =
   (SOURCE =
     (METHOD = FILE)
     (METHOD_DATA =
       (DIRECTORY = your_wallet_folder_path)
     )
   )
   
SQLNET.AUTHENTICATION_SERVICES = (TCPS,NTS,BEQ)
SSL_CLIENT_AUTHENTICATION = FALSE
SSL_CIPHER_SUITES = (SSL_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA)
-----------------------------------------------------------------------------------------
  1. 从 API 地址下载并保存的证书 - 它将在下一步添加到钱包中

    • 有几种类型 - 我都得到了它们 - 有效的是链 .p7c
  2. 使用 Walet Manager 应用程序创建新钱包(类型 .p12)

    • 请求的证书
    • 添加了受信任的证书扩展名 .p7c(链)
    • 打开钱包菜单并选中自动登录框
    • 保存在文件夹your_wallet_folder_path中的钱包
  • 在 Oracle 文件夹下的“所有程序”菜单中找到它enter image description here
  1. 关于plsql代码
    • 将参数(如果有的话)直接放在 URL 中,使用特殊字符的串联,例如 &
        -- v_url  := v_endpoint || v_path || '?api-version=3.0' || '&' || 'from=hr' || '&' || 'to=en'
  • 如果内容(正文)中预期,则构造 propper json 对象
Select JSON_ARRAYAGG(JSON_OBJECT(KEY 'text' VALUE 'some text in some language') RETURNING CLOB) Into v_body From Dual;

PL/SQL 代码 - 用于文本翻译 api

create or replace procedure "TEST"
is
BEGIN
    Declare
        v_key       VarChar2(64) := 'your api key';
        v_endpoint  VarChar2(64) := 'https://api.some_api_addres.com';
        v_path      VarChar2(64) := '/translate';
        v_location  VarChar2(64) := 'another api check';
      --
        v_body      CLOB := empty_clob();
        v_buffer    VarChar2(32767);
        --
        mReq        UTL_HTTP.req;
        mResp       UTL_HTTP.resp;
        v_url       VarChar2(128) := v_endpoint || v_path || '?api-version=3.0' || '&' || 'from=hr' || '&' || 'to=en';
    Begin
         Select JSON_ARRAYAGG(JSON_OBJECT(KEY 'text' VALUE 'some text in some language') RETURNING CLOB) Into v_body From Dual;

        UTL_HTTP.SET_BODY_CHARSET('UTF-8');
        UTL_HTTP.set_transfer_timeout (30);
        UTL_HTTP.SET_WALLET('file:your_wallet_folder_path', 'your_wallet_password');

        mReq := UTL_HTTP.BEGIN_REQUEST(v_url, 'POST');
        
        UTL_HTTP.SET_HEADER(mReq, 'Your-Api-Subscription-Key', v_key);
        UTL_HTTP.SET_HEADER(mReq, 'Your-Api-Some-Other-Check', v_location);
        UTL_HTTP.SET_HEADER(mReq, 'ClientTraceUUID', MK_GUID());  -- constructs uuid
        UTL_HTTP.SET_HEADER(mReq, 'Content-type', 'application/json');
        UTL_HTTP.SET_HEADER(mReq, 'Content-Length', length(v_body));
        
        UTL_HTTP.WRITE_TEXT(mReq, v_body);

        mResp := UTL_HTTP.GET_RESPONSE(mReq);

        begin
            loop
                utl_http.read_line(mResp, v_buffer);
                dbms_output.put_line(v_buffer);
            end loop;
            utl_http.end_response(mResp);
        exception
            when utl_http.end_of_body then
                utl_http.end_response(mResp);
        end;

    Exception
        WHEN OTHERS THEN
            dbms_output.put_line(utl_http.get_detailed_sqlerrm);
            utl_http.end_response(mResp);
    End;
END;    

评论

0赞 amila upendra 11/22/2023
您是如何授予完全控制权限的?您能否提供 ACL 代码。
0赞 amila upendra 11/22/2023
我对 Oracle Wallet 感到困惑。你能告诉我你是如何创建Oracle Wallet并添加证书的吗?我以管理员身份创建了打开CMD的钱包,然后添加了带有.cer文件的证书。在我的证书导出向导中找不到 .p7c,我可以找到 .p7b
0赞 d r 11/22/2023
@amilaupendra 刚刚发布了更新。完全控制是数据库服务器操作系统上的文件夹,我的是 Windows。Wallet Manager 是 Oracle 文件夹下所有程序菜单上的应用程序。很抱歉错过了在答案中告诉它。该应用程序非常简单明了......
0赞 amila upendra 11/22/2023
@d r 链式证书和存储证书(.cer / .crt)有什么区别。我刚刚下载了证书,并获得了 base-64 编码的 X.509(.cer) 并存储在钱包中。我错了吗?
0赞 d r 11/23/2023
@amilaupendra我真的不知道。据我了解 - 对于 https 第三方连接,Oracle 需要钱包类型 .p12(钱包管理器应用程序的默认值),并且该类型的钱包不会以 .crt/.cer/.der/....证书可以。就我而言,即使是单个 .p7c 也不起作用 - 只是链接 .p7c。我想在另一边(api)也有一些东西也应该满足。只是不知道。不好意思。