使用apex_web_service调用REST服务遇ORA-29273/ORA-28759错误求助
问题描述
我正尝试在Oracle APEX中使用apex_web_service.make_rest_request调用Autenticacao.gov的REST服务。已创建钱包并导入所需证书,通过p_wallet_path传入钱包路径,但仍收到错误:ORA-29273: HTTP请求失败、ORA-28759: 无法打开文件(钱包)。
代码示例
DECLARE l_response CLOB; l_json_obj JSON_OBJECT_T; l_json_array JSON_ARRAY_T; BEGIN l_json_array := JSON_ARRAY_T(); l_json_array.append(get_remote_server('NIC')); l_json_array.append(get_remote_server('NIF')); l_json_array.append(get_remote_server('FirstName')); l_json_array.append(get_remote_server('LastName')); l_json_array.append(get_remote_server('FullName')); l_json_array.append(get_remote_server('BirthDate')); l_json_array.append(get_remote_server('Nationality')); l_json_array.append(get_remote_server('NationalityCode')); l_json_array.append(get_remote_server('Gender')); l_json_array.append(get_remote_server('CCNationality')); l_json_array.append(get_remote_server('AddressXML')); l_json_array.append(get_remote_server('DocType')); l_json_array.append(get_remote_server('DocNumber')); l_json_array.append(get_remote_server('DocNationality')); l_json_array.append(get_remote_server('DocValidityDate')); l_json_obj := JSON_OBJECT_T(); l_json_obj.put('attributesName', l_json_array); l_json_obj.put('token', :token); apex_web_service.g_request_headers(1).name := 'Content-Type'; apex_web_service.g_request_headers(1).value := 'application/json; charset=utf-8'; apex_web_service.g_request_headers(2).name := 'Authorization'; apex_web_service.g_request_headers(2).value := 'Bearer ' || :token; l_response := apex_web_service.make_rest_request( p_url => 'https://preprod.autenticacao.gov.pt/oauthresourceserver/api/AttributeManager', p_http_method => 'POST', p_wallet_path => 'file:///C:/Users/samuel.luis/oracle_wallet/https_wallet', p_body => l_json_obj.to_string ); HTP.p(l_response); END;
错误信息
ORA-29273 ORA-28759: failure to open file (wallet)
备注
钱包在本地机器创建,包含证书链。
疑问
- 钱包是否必须放置在数据库服务器上?
- 若需放置,APEX/ORDS环境下的正确存储位置是什么,
p_wallet_path的正确值格式是怎样的? - 是否需要使用
DBMS_NETWORK_ACL_ADMIN为该外部端点配置额外的ACL权限?
解答
1. 钱包必须放置在数据库服务器上
是的,数据库进程无法直接访问本地客户端机器的文件系统。你当前指定的C:/Users/...路径是本地机器路径,数据库服务器无法读取,这是触发ORA-28759错误的直接原因。必须将钱包文件迁移到数据库服务器的文件系统中,且确保数据库进程(通常为oracle用户)对该路径拥有读权限。
2. APEX/ORDS环境下的钱包存储位置与路径格式
推荐存储位置:
- 可放在数据库服务器Oracle主目录下的专用钱包目录,例如Linux/Unix系统的
$ORACLE_BASE/admin/<SID>/wallet/,或Windows系统的%ORACLE_BASE%\admin\<SID>\wallet\; - 也可选择ORDS配置目录下的子目录,如
$ORDS_HOME/config/wallets/,但需确保ORDS进程和数据库进程都能访问该路径。
无论选择哪个位置,都要配置正确的目录权限:Linux/Unix下给oracle用户分配读权限,Windows下给数据库服务账号分配读权限。
- 可放在数据库服务器Oracle主目录下的专用钱包目录,例如Linux/Unix系统的
p_wallet_path的正确格式:- Linux/Unix系统:使用
file:///前缀加绝对路径,例如file:///u01/app/oracle/admin/ORCL/wallet/https_wallet; - Windows系统:使用
file:///前缀,路径中的反斜杠需改为正斜杠,或使用双反斜杠,例如file:///C:/oracle/admin/ORCL/wallet/https_wallet或file:///C:\\oracle\\admin\\ORCL\\wallet\\https_wallet。
- Linux/Unix系统:使用
3. 需要配置ACL权限
是的,必须通过DBMS_NETWORK_ACL_ADMIN包为执行APEX代码的数据库用户配置访问目标端点的权限,同时要确保钱包所在目录的操作系统权限配置正确。
示例ACL配置代码(替换YOUR_USER为实际数据库用户):
BEGIN DBMS_NETWORK_ACL_ADMIN.CREATE_ACL( acl => 'autenticacao_gov_acl.xml', description => 'ACL for Autenticacao.gov API', principal => 'YOUR_USER', is_grant => TRUE, privilege => 'connect' ); DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL( acl => 'autenticacao_gov_acl.xml', host => 'preprod.autenticacao.gov.pt', lower_port => 443, upper_port => 443 ); COMMIT; END; /
此外,还要确保该数据库用户拥有EXECUTE权限访问apex_web_service包。
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

