oracle - 在 oracle 钱包中指定证书和密钥
问题描述
我在 PL/SQL 中发出 POST 请求,但遇到了Certificate validation failure
错误。如果我在数据库之外运行它,在 cURL 或 Postman 中都可以正常工作。
在后面的程序中,我需要指定客户端证书、私钥和 CA 证书。在 cURL 我使用--cert
,--key
和--cacert
.
在 PL/SQL 中运行时,我只能指定存储这些文件的钱包,但我似乎没有指定要使用哪个证书和密钥的选项,我认为这就是我遇到问题的原因?
declare
req utl_http.req;
res utl_http.resp;
url varchar2(4000) := 'https://server/';
buffer varchar2(4000);
begin
utl_http.set_wallet('file:wallet_path');
req := utl_http.begin_request(url,'POST');
utl_http.set_header(req,'header_name','header_text');
res := utl_http.get_response(req);
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;
/
解决方案
UTL_HTTP 没有这样的功能(并且可能有一些错误),但您可以尝试使用 Java 存储过程。它更加灵活,我仅通过这种方式修复了“证书验证失败”错误。
有一个POST请求函数的例子:
CREATE OR REPLACE JAVA SOURCE NAMED "example/HttpUtil" AS
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.sql.Blob;
public class HttpUtil {
public static boolean doRequest(String link, Blob requestBody, Blob[] responseBody, String[] message) {
String res = "Success";
boolean result = true;
try {
request(link,requestBody,responseBody);
} catch (Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
res = sw.toString();
result = false;
}
message[0] = res;
return result;
}
public static void request(String link, Blob requestBody, Blob[] responseBody) throws Exception {
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Proxy-Connection", "Keep-Alive");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
con.setRequestProperty("Content-Length", String.valueOf(requestBody.length()));
DataOutputStream outputStream = new DataOutputStream(con.getOutputStream());
InputStream reqStream = requestBody.getBinaryStream();
byte[] buff = new byte[1024];
int len = 0;
while ((len = reqStream.read(buff)) != -1) {
outputStream.write(buff, 0, len);
}
int status = con.getResponseCode();
InputStream in;
if (status >= 400) {
in = con.getErrorStream();
} else {
in = con.getInputStream();
}
OutputStream out = responseBody[0].setBinaryStream(0);
byte[] buf = new byte[1024];
int n;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
in.close();
con.disconnect();
out.flush();
}
}
/
ALTER JAVA SOURCE "example/HttpUtil" COMPILE;
CREATE OR REPLACE FUNCTION http_request (is_url IN VARCHAR2,
i_body IN BLOB,
io_resp IN OUT NOCOPY BLOB,
o_message OUT VARCHAR2)
RETURN BOOLEAN
AS LANGUAGE JAVA
NAME 'HttpUtil.doRequest(java.lang.String, java.sql.Blob, java.sql.Blob[], java.lang.String[]) return boolean';
推荐阅读
- c# - AmazonAppSyncClient() 构造函数未在 xamarin 中实现异常
- php - 属性对 Sendinblue API 无效
- javascript - 需要帮助使用 vue-router 加载组件
- android - 如何在自定义视图中定义相对触摸大小?
- angular - 如何有效地将带有数据的大型 json 加载到角度 8 上的多个表中?
- javascript - React - 计算元素之间的较大值仅部分工作
- uml - 我应该使用哪种类型的图表(基础设施)?
- xml - XML 模式验证。项目数不定的无序列表
- flutter - Flutter 中如何改变 ScrollController 的偏移值?
- input - 如何在 ipython 中创建多行输入?