使用客户管理的 Wallet 进行外部调用
当自治 AI 数据库需要通过 HTTP/HTTPS 访问互联网上的数据时,可以使用 UTL_HTTP 程序包。通过 UTL_HTTP 程序包,可以直接从 SQL 和 PL/SQL 进行 HTTP 标注。
如果您要调用 HTTPS 端点,则必须配置 Oracle Wallet 。自治 AI 数据库需要一个 wallet,其中包含您的数据库将连接到的任何 HTTPS 端点的可信根证书和中间证书。UTL_HTTP 软件包使用此 wallet 建立安全的 SSL/TLS 连接。您可以使用 orapki 实用程序创建和管理 wallet。
注:普通 HTTP(非 HTTPS)请求不需要 Oracle Wallet。
以下各节介绍了如何配置和使用客户管理的 wallet,以通过自治 AI 数据库上的 UTL_HTTP 程序包进行出站 HTTPS 调用。
使用客户管理的 Wallet 和外部调用时的先决条件
开始之前,确保您具有:
-
使用可运行 PL/SQL 并配置
UTL_HTTP的账户访问自治 AI 数据库。 -
访问目标 HTTPS 端点及其完整证书链(根证书 + 中间证书)。
-
可运行
orapki以创建和验证 Oracle Wallet 的工作站。您需要安装 Oracle Database 才能获得orapki实用程序。有关详细信息,请参见 Installing Oracle Database 。
准备客户管理的钱包
在此步骤中,您将先在工作站上创建并验证 wallet,然后再将其上载到自治 AI 数据库。
获取或创建客户管理的钱包
使用 orapki 的示例:
-- Create an SSL Wallet and load the Root CERTs using orapki utility
$ORACLE_HOME/bin/orapki wallet create -wallet /u01/web/wallet -pwd ********
$ORACLE_HOME/bin/orapki wallet add -wallet /u01/web/wallet -trusted_cert -cert MyWebServer.cer -pwd ********
-- Store the credentials in the SSL Wallet using mkstore utility
$ORACLE_HOME/bin/mkstore -wrl /u01/web/wallet -createCredential secret-from-the-wallet 'example@oracle.com'
********Enter wallet password: ********
验证 Wallet
$ORACLE_HOME/bin/orapki wallet display -wallet /u01/web/wallet
您应看到列出的所有导入的证书。
上载 Wallet
客户管理的 wallet 准备就绪(包括任何必需的自签名/root/中间证书)后,将 wallet 文件上载到 Oracle Cloud Infrastructure (OCI) 对象存储中的位置。
将客户管理的 wallet 与 UTL_HTTP 一起使用
本部分介绍如何从对象存储下载 wallet,允许通过网络访问 HTTPS 端点,然后使用 UTL_HTTP 程序包进行 HTTPS 调用。
-
创建用于对象存储访问的身份证明:
BEGIN DBMS_CLOUD.CREATE_CREDENTIAL(credential_name => 'DEF_CRED_NAME', username => 'user1@example.com', password => 'password' ); END; /为
username和password提供的值取决于您使用的云对象存储服务。这将创建用于访问客户管理的 wallet 所在的云对象存储的身份证明。 -
为 wallet 创建(或重用)目录对象:
使用现有目录,或者为 wallet 文件创建新目录。例如:
CREATE DIRECTORY wallet_dir AS 'directory_path_of_your_choice';有关创建目录的信息,请参见 Create Directory in Autonomous AI Database 。
-
获取绝对目录路径:
调用
UTL_HTTP.SET_WALLET时将需要绝对目录路径。SELECT DIRECTORY_NAME, DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME = '<wallet_dir>'; -
将 wallet 文件从对象存储下载到目录中:
使用
DBMS_CLOUD.GET_OBJECT将 wallet 文件复制到目录中。例如:BEGIN DBMS_CLOUD.GET_OBJECT( credential_name => 'DEF_CRED_NAME', object_uri => 'https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname/o/cwallet.sso', directory_name => 'WALLET_DIR'); END; /在此示例中,
namespace-string是 Oracle Cloud Infrastructure 对象存储名称空间,bucketname是存储桶名称。有关详细信息,请参阅了解对象存储名称空间。 -
允许对 HTTPS 端点的出站网络访问 (ACL):
必须允许数据库用户/方案通过网络访问目标主机。
BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'api.example.com', ace => xs$ace_type( privilege_list => xs$name_list('CONNECT','HTTP','RESOLVE'), principal_name => 'ADMIN', principal_type => xs_acl.ptype_db ) ); END; /在 Exadata Cloud@Customer 部署上,您还需要设置代理,如下所示:
BEGIN UTL_HTTP.SET_PROXY('www-proxy.us.oracle.com:80', 'oracle.com'); END; / -
使用
UTL_HTTP进行 HTTPS 调用:简单 GET 请求:
DECLARE l_http_req UTL_HTTP.req; l_http_resp UTL_HTTP.resp; l_response VARCHAR2(32767); BEGIN utl_http.set_wallet('file:<absolute_directory_path_from_step_3>'); l_http_req := UTL_HTTP.BEGIN_REQUEST('https://api.example.com/status'); l_http_resp := UTL_HTTP.GET_RESPONSE(l_http_req); LOOP UTL_HTTP.READ_LINE(l_http_resp, l_response, TRUE); DBMS_OUTPUT.PUT_LINE(l_response); END LOOP; UTL_HTTP.END_RESPONSE(l_http_resp); END; /带有 JSON 有效负载的 POST 请求:
DECLARE l_req UTL_HTTP.req; l_resp UTL_HTTP.resp; l_line VARCHAR2(32767); BEGIN utl_http.set_wallet('file:<absolute_directory_path_from_step_3>'); l_req := UTL_HTTP.BEGIN_REQUEST( url => 'https://api.example.com/data', method => 'POST' ); UTL_HTTP.SET_HEADER(l_req, 'Content-Type', 'application/json'); UTL_HTTP.WRITE_TEXT(l_req, '{"key":"value"}'); l_resp := UTL_HTTP.GET_RESPONSE(l_req); LOOP UTL_HTTP.READ_LINE(l_resp, l_line, TRUE); DBMS_OUTPUT.PUT_LINE(l_line); END LOOP; UTL_HTTP.END_RESPONSE(l_resp); END; /
常见错误的故障排除:
证书链错误
错误:ORA-29024: Certificate validation failure
-
可能缺少根证书和中间证书。
-
目标端点可能正在使用新的 CA - 重新下载完整的证书链并重新创建 wallet。
Wallet 路径错误
ORA-28759: Failure to open file
-
SET_WALLET中的 wallet 路径不正确。 -
缺少
file:前缀。 -
上载的 wallet 文件不在目录中。
握手故障
ORA-24263 / ORA-29005
-
TLS 协议不匹配。
-
证书错误或已过期。
-
端点强制 TLS > 1.2
将客户管理的 Wallet 用于调度程序电子邮件通知 (SMTP)
本节说明如何将调度程序电子邮件通知配置为通过 TLS (STARTTLS) 将 SMTP 服务器与客户管理的 wallet 一起使用。
在开始之前,请确保您已准备好客户管理的 wallet(在本地创建、验证并上载到对象存储)。有关详细信息,请参阅“准备客户管理的 Wallet”。
要将客户管理的 wallet 与调度程序电子邮件服务器一起使用,请执行以下操作:
-
创建用于对象存储访问的身份证明:
可以使用
DBMS_CLOUD.CREATE_CREDENTIAL创建用于访问云对象存储的身份证明。BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'DEF_CRED_NAME', username => 'user1@example.com', password => 'password' ); END; /为
username和password提供的值取决于您使用的云对象存储服务。这将创建用于访问客户管理的 wallet 所在的云对象存储的身份证明。 -
为 wallet 创建(或重用)目录对象:
使用现有目录,或者为 wallet 文件创建新目录。例如:
CREATE DIRECTORY wallet_dir AS 'directory_path_of_your_choice';有关创建目录的信息,请参见 Create Directory in Autonomous AI Database 。
-
获取绝对目录路径:
调用
UTL_HTTP.SET_WALLET时将需要绝对目录路径。SELECT DIRECTORY_NAME, DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME = '<wallet_dir>'; -
将 wallet 文件从对象存储下载到目录中:
使用
DBMS_CLOUD.GET_OBJECT将 wallet 文件复制到目录中。例如:BEGIN DBMS_CLOUD.GET_OBJECT( credential_name => 'DEF_CRED_NAME', object_uri => 'https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname/o/cwallet.sso', directory_name => 'WALLET_DIR'); END; /在此示例中,
namespace-string是 Oracle Cloud Infrastructure 对象存储名称空间,bucketname是存储桶名称。有关详细信息,请参阅了解对象存储名称空间。 -
配置调度程序电子邮件 (SMTP + STARTTLS):
运行命令以设置调度程序,以便为调度程序作业通知发送 SMTP 电子邮件:
EXEC DBMS_CLOUD.CREATE_CREDENTIAL('EMAIL_CRED', '<user_ocid>', '<password>'); GRANT EXECUTE ON admin.EMAIL_CRED TO sys; EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE( 'EMAIL_SERVER', 'smtp.email.us-ashburn-1.oci.oraclecloud.com:587' ); EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE( 'EMAIL_SERVER_CREDENTIAL', 'EMAIL_CRED' ); EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE( 'EMAIL_SERVER_ENCRYPTION', 'STARTTLS' );这些命令执行以下操作:
-
设置调度程序 SMTP 端点 (
EMAIL_SERVER) -
在
EMAIL_CRED中存储 SMTP 登录详细信息并将调度程序指向它 -
使用
STARTTLS启用 TLS 加密
有关详细信息,请参阅 SET_SCHEDULER_ATTRIBUTE 过程。
-
-
为 wallet 密码创建身份证明:
创建身份证明以存储客户管理的 wallet 的密码。
BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'WALLET_CRED', username => 'any_user', password => 'password' ); END; /这将创建您在下一步中使用的身份证明,以提供客户管理的 wallet 的密码。
-
告诉调度程序 Wallet 的位置以及如何解锁它:
设置调度程序 wallet 目录和 wallet 身份证明。
BEGIN DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE( 'EMAIL_SERVER_WALLET_DIRECTORY', 'WALLET_DIR' ); DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE( 'EMAIL_SERVER_WALLET_CREDENTIAL', 'ADMIN.WALLET_CRED' ); END; / -
验证调度程序电子邮件配置:
查询
DBA_SCHEDULER_GLOBAL_ATTRIBUTE视图以验证您在前面步骤中设置的值。SELECT attribute_name, value FROM DBA_SCHEDULER_GLOBAL_ATTRIBUTE WHERE attribute_name LIKE 'EMAIL_SERVER%' ORDER BY 1, 2;ATTRIBUTE_NAME VALUE ------------------------------ ----------------------------------------------- EMAIL_SERVER smtp.email.us-ashburn-1.oci.oraclecloud.com:587 EMAIL_SERVER_CREDENTIAL "ADMIN"."EMAIL_CRED" EMAIL_SERVER_ENCRYPTION STARTTLS EMAIL_SERVER_WALLET_CREDENTIAL "ADMIN"."WALLET_CRED" EMAIL_SERVER_WALLET_DIRECTORY "WALLET_DIR"
引用
有用的 orapki 命令:
orapki wallet display -wallet <path> orapki wallet add -wallet <path>
-trusted_cert -cert <cert-file> orapki wallet create -wallet <path> -auto_login
wallet 目录结构样例:
cmw_wallet/
- ewallet.p12
- cwallet.sso