我正在尝试从PL / SQL块调用第三方Web服务。
对于使用SSL,我从网站下载了证书并安装在Oracle钱包中。
现在客户端需要双向SSL身份验证。怎么做到这一点?我是否需要在HTTP调用中添加其他内容?
以下是我正在使用的代码。
create or replace function GetDeptInfo( arg0 number ) return XmlType is
--// URL to call
SOAP_URL constant varchar2(1000) := 'https://google.com:7002/WebService-Annotation-context-root/MyCompanyPort';
SOAP_ENVELOPE constant varchar2(32767) :=
'<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://annotation/">
<env:Header/>
<env:Body>
<ns1:getDeptInfo>
<arg0>$arg0</arg0>
</ns1:getDeptInfo>
</env:Body>
</env:Envelope>';
--// we'll identify ourselves using an IE9/Windows7 generic browser signature
C_USER_AGENT constant varchar2(4000) := 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)';
--// these variables need to be set if web access
--// is via a proxy server
proxyServer varchar2(20) default null;
proxyUser varchar2(20) default null;
proxyPass varchar2(20) default null;
--// our local variables
soapEnvelope varchar2(32767);
proxyURL varchar2(4000);
request utl_http.req;
response utl_http.resp;
buffer varchar2(32767);
soapResponse clob;
xmlResponse XmlType;
eof boolean;
begin
--// create the SOAP envelope
soapEnvelope := replace( SOAP_ENVELOPE, '$arg0', arg0 );
--// our "browser" settings
utl_http.set_response_error_check( true );
utl_http.set_detailed_excp_support( true );
utl_http.set_cookie_support( true );
utl_http.set_transfer_timeout( 10 );
utl_http.set_follow_redirect( 3 );
utl_http.set_persistent_conn_support( true );
--// configure for web proxy access if applicable
if proxyServer is not null then
proxyURL := 'http://'||proxyServer;
if (proxyUser is not null) and (proxyPass is not null) then
proxyURL := Replace( proxyURL, 'http://', 'http://'||proxyUser||':'||proxyPass||'@' );
end if;
utl_http.set_proxy( proxyURL, null );
end if;
--// make the POST call to the web service
UTL_HTTP.set_wallet('file:/tmp/DEVF1MB/wallet', 'WalletPasswd123');
request := utl_http.begin_request( SOAP_URL, 'POST', utl_http.HTTP_VERSION_1_1 );
utl_http.set_header( request, 'User-Agent', C_USER_AGENT );
utl_http.set_header( request, 'Content-Type', 'text/xml; charset=utf-8' );
utl_http.set_header( request, 'Content-Length', length(soapEnvelope) );
utl_http.set_header( request, 'SoapAction', 'http://www.webserviceX.NET/GetWeather' );
utl_http.write_text( request, soapEnvelope );
--// read the web service HTTP response
response := utl_http.get_response( request );
dbms_lob.CreateTemporary( soapResponse, true );
eof := false;
loop
exit when eof;
begin
utl_http.read_line( response, buffer, true );
if length(buffer) > 0 then
dbms_lob.WriteAppend(
soapResponse,
length(buffer),
buffer
);
end if;
exception when utl_http.END_OF_BODY then
eof := true;
end;
end loop;
utl_http.end_response( response );
--// as the SOAP responds with XML, we convert
--// the response to XML
xmlResponse := XmlType( soapResponse );
dbms_lob.FreeTemporary( soapResponse );
return( xmlResponse );
exception when OTHERS then
if soapResponse is not null then
dbms_lob.FreeTemporary( soapResponse );
end if;
raise;
end;
答案 0 :(得分:1)
这是我的2美分:(并且有效;-))
首先,我成功地使用utl_http调用一个Web服务到一个关闭的wsdl,它是一个http URL。
接下来,当网络服务主机将网址更改为https时,我将其证书导入我的电子钱包后仍然取得了成功。在做begin_request
之前有这个陈述:
UTL_HTTP.SET_WALLET ('file:/tmp/wallet/dp_wallet','pass1234');
(我在tmp文件夹中测试它,我有权测试)。它也有效,直到他们强制执行双向身份验证。 我一直在寻找一种方法,在拨打电话时发送(提供)我的证书。我没有成功:致命的SSL错误。
对你有用的几个技巧:
请勿将钱包密码用作&#34;密码&#34;。或者任何简单。请使用数字。如果有的话,错误消息并不明显。我使用smart1234并且它有效。
您必须已添加解析,将当前用户连接到网络acl。请添加以下内容以及钱包(这有所不同):
BEGIN
DBMS_NETWORK_ACL_ADMIN.ASSIGN_WALLET_ACL('www.xml','file:/tmp/wallet/dp_wallet');
END;
/
COMMIT;
提供对世界的读取权限(以防万一)。错误很容易识别。它将是:&#34;无法打开文件&#34;
使用测试sql是一个好主意,但并不意味着你在实际的begin_request中取得了成功:
SELECT utl_http.request('https://dpserver:4401/tuxops/LookUp',
'',
'file:/tmp/wallet/dp_wallet',
'smart1234')
FROM dual;
退出并从此用户重新登录!
有时需要几分钟才能生效!我很难测试,因为我忽略了这两个。
如果您提供了3次或更多次错误密码或其他故障,则可能会有延迟成功。 简单的选择是注销并重新登录。这会重置会话错误。
希望我的发现对你有用:)
答案 1 :(得分:0)
从概念上讲,您需要与第三方交换SSL证书,在您的客户端为2路SSL生成。 它完全取决于Web服务(wsdl)提供程序的配置。 通常,https模式下有两种类型的web服务配置。
如果提供商已将其Web服务配置为“使用客户端身份验证进行https”,那么您必须与他交换SSL证书(双向SSL)。在这种情况下,您还需要提供从客户端生成的SSL证书,以便在第三方服务器上安装,反之亦然。但只有在提供程序已配置为以此方式与您进行该Web服务通信时,它才有效。
在第二个选项中,通常信任您(客户)端的第三方Web服务端点URL工作,无需交换证书。