如何在Oracle APEX_WEB_SERVICE.MAKE_REST_REQUEST中安全存储代理账户密码?
安全存储代理凭据并在
apex_web_service.make_rest_request中引用的方案 方案1:使用Oracle Wallet存储代理凭据
Oracle Wallet是官方推荐的敏感凭据安全存储方案,会加密存储用户名、密码等信息,仅授权数据库用户可访问。
操作步骤:
- 创建Oracle Wallet(若未创建):
执行命令行工具mkstore创建Wallet:mkstore -wrl /指定/wallet存储路径 -create - 向Wallet添加代理凭据:
其中mkstore -wrl /指定/wallet存储路径 -createCredential proxy.my-domain.local my-domain\my-user my-passwordproxy.my-domain.local为代理服务器地址,后接用户名和密码。 - 配置数据库Wallet路径:
修改sqlnet.ora文件,添加或更新以下参数:WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY = /指定/wallet存储路径))) SQLNET.WALLET_OVERRIDE = TRUE - 代码中引用Wallet凭据:
无需在p_proxy_override中明文填写用户名密码,仅指定代理地址即可,Oracle会自动从Wallet匹配对应凭据:
注意:确保执行代码的数据库用户拥有Wallet访问权限,且Wallet已正确加载。apex_web_service.make_rest_request (p_url => l_url ,p_http_method => 'POST' ,p_body => request_body_v ,p_transfer_timeout => 10 ,p_proxy_override => 'proxy.my-domain.local');
方案2:使用APEX工作区凭据(适用于APEX环境)
如果代码运行在Oracle APEX应用中,可利用APEX内置的工作区凭据功能,它会加密存储凭据,且仅授权应用可访问。
操作步骤:
- 登录APEX工作区,进入应用构建器 → 目标应用 → 共享组件 → 凭据 → 创建
- 填写凭据信息:
- 凭据名称:例如
PROXY_CREDENTIAL - 用户名:
my-domain\my-user - 密码:
my-password
- 凭据名称:例如
- 代码中通过凭据名称调用:
使用apex_credential.get_credential获取凭据后拼接代理字符串:
该方案由APEX统一管理凭据,无需操作数据库Wallet,权限控制更灵活。DECLARE l_proxy_user VARCHAR2(100); l_proxy_pwd VARCHAR2(100); l_proxy_str VARCHAR2(200); BEGIN apex_credential.get_credential( p_credential_name => 'PROXY_CREDENTIAL', p_username => l_proxy_user, p_password => l_proxy_pwd ); l_proxy_str := l_proxy_user || ':' || l_proxy_pwd || '@proxy.my-domain.local'; apex_web_service.make_rest_request (p_url => l_url ,p_http_method => 'POST' ,p_body => request_body_v ,p_transfer_timeout => 10 ,p_proxy_override => l_proxy_str); END;
方案3:使用数据库加密列存储(自定义加密)
若上述方案不适用,可将凭据存储在数据库加密列中,通过DBMS_CRYPTO包加密解密,同时严格控制表访问权限。
操作步骤:
- 创建带加密列的凭据表:
CREATE TABLE proxy_credentials ( id NUMBER PRIMARY KEY, proxy_host VARCHAR2(100), username VARCHAR2(100), password RAW(2000) -- 存储加密后的密码 ); - 编写加密解密函数(需先授予
DBMS_CRYPTO权限):
注意:加密密钥和IV需妥善保管,避免硬编码在代码中,可存储至Oracle Wallet。CREATE OR REPLACE FUNCTION encrypt_pwd(p_pwd VARCHAR2) RETURN RAW IS l_key RAW(128) := UTL_I18N.STRING_TO_RAW('自定义加密密钥', 'AL32UTF8'); l_iv RAW(128) := UTL_I18N.STRING_TO_RAW('自定义IV值', 'AL32UTF8'); BEGIN RETURN DBMS_CRYPTO.ENCRYPT( src => UTL_I18N.STRING_TO_RAW(p_pwd, 'AL32UTF8'), typ => DBMS_CRYPTO.AES_CBC_PKCS5, key => l_key, iv => l_iv ); END; / CREATE OR REPLACE FUNCTION decrypt_pwd(p_encrypted_pwd RAW) RETURN VARCHAR2 IS l_key RAW(128) := UTL_I18N.STRING_TO_RAW('自定义加密密钥', 'AL32UTF8'); l_iv RAW(128) := UTL_I18N.STRING_TO_RAW('自定义IV值', 'AL32UTF8'); BEGIN RETURN UTL_I18N.RAW_TO_STRING( DBMS_CRYPTO.DECRYPT( src => p_encrypted_pwd, typ => DBMS_CRYPTO.AES_CBC_PKCS5, key => l_key, iv => l_iv ), 'AL32UTF8' ); END; / - 插入加密后的凭据:
INSERT INTO proxy_credentials (id, proxy_host, username, password) VALUES (1, 'proxy.my-domain.local', 'my-domain\my-user', encrypt_pwd('my-password')); COMMIT; - 代码中读取并解密凭据:
该方案需自行管理加密逻辑,建议仅在其他方案不可行时使用,同时严格限制DECLARE l_proxy_user VARCHAR2(100); l_proxy_pwd VARCHAR2(100); l_proxy_host VARCHAR2(100); l_proxy_str VARCHAR2(200); BEGIN SELECT username, decrypt_pwd(password), proxy_host INTO l_proxy_user, l_proxy_pwd, l_proxy_host FROM proxy_credentials WHERE id = 1; l_proxy_str := l_proxy_user || ':' || l_proxy_pwd || '@' || l_proxy_host; apex_web_service.make_rest_request (p_url => l_url ,p_http_method => 'POST' ,p_body => request_body_v ,p_transfer_timeout => 10 ,p_proxy_override => l_proxy_str); END;proxy_credentials表的访问权限。
内容的提问来源于stack exchange,提问作者bydman
相关产品推荐
相关产品推荐

