使用来自带有PL / SQL的Oracle存储过程的基于cookie的身份验证来使用SOAP Web服务

时间:2015-12-10 12:37:18

标签: oracle web-services cookies soap plsql

我们正在尝试直接从Oracle DB存储过程使用带有PL / SQL的安全(https)Web服务。有一个单独的Web服务用于用户操作(登录/注销)及其文档状态

  

成功登录后,会创建会话cookie。必须将Web服务客户端配置为接收cookie。登录后,只要它们包含登录收到的会话cookie,后续调用就会成功。

但是我们不知道如何从PL / SQL存储和使用该cookie。任何帮助都会得到满足。

注意:

  • 我们成功创建了Oracle Wallet,将Web服务的证书添加到钱包中,并将其分配给请求,如下所示:

    Declare
      ...
      v_req_context    UTL_HTTP.REQUEST_CONTEXT_KEY;
      ...
    Begin
      ...
      v_req_context := UTL_HTTP.CREATE_REQUEST_CONTEXT(wallet_path => 'file:'||ssl_cert_wallet_path,
                                                       wallet_password => ssl_cert_wallet_password);
      v_http_request := UTL_HTTP.BEGIN_REQUEST(url             => 'https://<url_to_webservice_wsdl>',
                                               method          => 'POST',
                                               http_version    => 'HTTP/1.1',
                                               request_context => v_req_context);
      ...
    End;
    
  • 我们正在向用户服务发出如下请求:

    Begin
      -- SOAP Authentication request parameters
      v_string_request := '<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:examples:userService">
                             <soapenv:Header/>
                             <soapenv:Body>
                               <urn:' || v_service_operation || ' soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:urn="' || v_service_namespace || '/">
                                 <userId>' || p_username || '</userId>
                                 <password>' || p_password || '</password>
                                 <lang>' || p_lang || '</lang>
                               </urn:' || v_service_operation || '>
                             </soapenv:Body>
                           </soapenv:Envelope>';
    
      UTL_HTTP.SET_TRANSFER_TIMEOUT(60);
    
      v_http_request := UTL_HTTP.BEGIN_REQUEST(url             => v_host_name || ':' || v_port || v_service_posfix,
                                               method          => 'POST',
                                               http_version    => 'HTTP/1.1',
                                               request_context => v_req_context);
    
      UTL_HTTP.SET_HEADER(v_http_request, 'Host', v_host_name || ':' || v_port);
      UTL_HTTP.SET_HEADER(v_http_request, 'Connection', 'close');
      UTL_HTTP.SET_HEADER(v_http_request, 'Content-Type', 'text/xml;charset=UTF-8');
      UTL_HTTP.SET_HEADER(v_http_request, 'SOAPAction', '"' || v_service_operation || '"');
      UTL_HTTP.SET_HEADER(v_http_request, 'Content-Length', length(v_string_request));
    
      <<login_request_loop>>
      for i in 0..CEIL(LENGTH(v_string_request) / v_buffer_size) - 1
      loop
        v_substring_msg := SUBSTR(v_string_request, i * v_buffer_size + 1, v_buffer_size);
    
        begin
          v_raw_data := UTL_RAW.CAST_TO_RAW(c => v_substring_msg);
          UTL_HTTP.WRITE_RAW(r => v_http_request, data => v_raw_data);
        exception
          when NO_DATA_FOUND then EXIT login_request_loop;
        end;
      end loop login_request_loop;
    
      -- SOAP Authentication request
      v_http_response := UTL_HTTP.GET_RESPONSE(v_http_request);
      ...
    End;
    

1 个答案:

答案 0 :(得分:0)

让我放弃答案以备将来使用:

如果您尝试使用的Web服务是安全(https)Web服务,则不要在标头中单独设置Host。 如果删除该行,代码就像魅力一样:

UTL_HTTP.SET_HEADER(v_http_request, 'Host', v_host_name || ':' || v_port);
PS:我发现这一切都是我自己,所以我不能参考任何来源。