首页 > 解决方案 > 从 wsdl 将安全标头传递给肥皂信封

问题描述

我从 PLSQL 调用 SOAP 服务我有这个wsld 用于肥皂服务。我有以下 SOAP 信封可以从 PLSQL 调用

 <soapenv:Body><cus:SaveSales><!--Optional:--><cus:salesRequestENDataContract><cus1:Subcontractor>
    <cus1:CompanyCode>75</cus1:CompanyCode><cus1:RegionCode>98</cus1:RegionCode><cus1:StoreCode>UMT41</cus1:StoreCode>
    <cus1:CashTillCode>1</cus1:CashTillCode><cus1:CashierCode>'||FETCH_HEADER.CASH_NAT_ID||'</cus1:CashierCode></cus1:Subcontractor>
    <cus1:SalesDate><cus1:Day>'||FETCH_HEADER.GUN||'</cus1:Day><cus1:Month>'||FETCH_HEADER.AY||'</cus1:Month><cus1:Year>'||FETCH_HEADER.YIL||'</cus1:Year>
    <cus1:Hour>'||FETCH_HEADER.SAAT||'</cus1:Hour><cus1:Minute>'||FETCH_HEADER.DAKIKA||'</cus1:Minute><cus1:Second>'||FETCH_HEADER.SANIYE||'</cus1:Second>
    </cus1:SalesDate><!--Optional:--><cus1:InvoiceNumber>'||FETCH_HEADER.DOC_PROV_NO||'</cus1:InvoiceNumber><cus1:Customer>
    <cus1:IdentityType>'||FETCH_HEADER.DOC_TYPE||'</cus1:IdentityType><cus1:PassportNo>'||FETCH_HEADER.PASSPORT_NO||'</cus1:PassportNo>
    <cus1:CustomerName>'||FETCH_HEADER.PASS_SUR_NAME||'</cus1:CustomerName><cus1:DateOfBirth>
    <cus1:Day>'||TO_CHAR(FETCH_HEADER.PAS_DOB,'DD')||'</cus1:Day><cus1:Month>'||TO_CHAR(FETCH_HEADER.PAS_DOB,'MM')||'</cus1:Month>
    <cus1:Year>'||TO_CHAR(FETCH_HEADER.PAS_DOB,'YYYY')||'</cus1:Year><cus1:Hour>0</cus1:Hour><cus1:Minute>0</cus1:Minute>
    <cus1:Second>0</cus1:Second></cus1:DateOfBirth><cus1:PassengerTypeCode>'||FETCH_HEADER.PASSENGER_TYPE||'</cus1:PassengerTypeCode>
    <cus1:Arrival_Departure_Code>2</cus1:Arrival_Departure_Code></cus1:Customer><cus1:SalesLine><!--Zero or more repetitions:-->
    <cus1:SalesLine><cus1:ProductGroupCode>99</cus1:ProductGroupCode><cus1:SalesQuantity>'||FETCH_HEADER.SUM_QTY||'</cus1:SalesQuantity>
    <cus1:LimitUnitQuantity>'||FETCH_HEADER.SUM_QTY||'</cus1:LimitUnitQuantity><!--Optional:--><cus1:DolarAmount>'||FETCH_HEADER.TENDER_AMOUNT*1.12||'</cus1:DolarAmount>
    <!--Optional:--><cus1:EuroAmount>'||FETCH_HEADER.TENDER_AMOUNT||'</cus1:EuroAmount></cus1:SalesLine></cus1:SalesLine></cus:salesRequestENDataContract>
    </cus:SaveSales></soapenv:Body></soapenv:Envelope>

当我从 PLSQ 调用 SOAP 服务时,它给我下面的错误

Response> content-length: "1743" Response> status_code: "500" Response> reason_phrase: "Internal Server Error" Response> http_version: "HTTP/1.1" Response> length: "347" === Print first 1000 lines of HTTP response... === [00]: <s:Envelope xmlns:s="schemas.xmlsoap.org/soap/envelope/… xmlns:a="docs.oasis-open.org/wss/2004/01/… xml:lang="en-US">An error occurred when verifying security for the message.</faultstring></s:Fault></s:Body></s:Envelope> 

所以它可能是也可能不是由于 SOAP 信封中包含的安全标头,但我不知道如何从附加的 WSDL 中获取这些标头。另请参阅下面的示例标题并指导如何附加信封

<soapenv:Header>
      <wsu:Security xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
         <sp:UsernameToken wsu:Id="UsernameToken-7" xmlns:wsu="http://docs.oasis-open.org/wss/2004/...tility-1.0.xsd">
            <wsse:Username>110001234</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/...0#PasswordText">1AB2C3DEF45G6A78</wsse:Password>
         </sp:UsernameToken>
      </wsse:Security>
      <ser:Profile>
         <ser:Name>1.0</ser:Name>
         <ser:Client>MyAdaptorName</ser:Client>
         <ser:Adapter>Adaptor</ser:Adapter>
         <ser:Machine>MyServer</ser:Machine>
      </ser:Profile>
   </soapenv:Header>

我想通过添加标题或其他内容作为捕获和解决错误的建议来解决这个问题。

更新

PROCEDURE SALES_XML_CUSTOMS_PRC
   IS

  v_len number;

    l_http_request   UTL_HTTP.req;
    l_http_response  UTL_HTTP.resp;
    l_buffer_size    NUMBER(10) := 30000;
    l_line_size      NUMBER(10) := 20000;
    l_lines_count    NUMBER(10) := 1000;
    l_string_request VARCHAR2(32767);
    l_line           VARCHAR2(30000);
    l_substring_msg  VARCHAR2(30000);
    l_raw_data       RAW(30000);
    l_clob_response  CLOB;
--    l_host_name      VARCHAR2(128) := '195.128.37.14';
    l_host_name      VARCHAR2(128) := 'inatestgumrukws.unifree.com.tr';
    l_port           VARCHAR2(128) := '443'; --80: http, 443: https
    l_resp_xml        XMLType;
    l_result_XML_node VARCHAR2(128);
    l_NAMESPACE_SOAP  VARCHAR2(128) := 'xmlns:ns0=''urn:sap-com:document:sap:rfc:functions''';
    l_response_Customername   VARCHAR2(128);
    l_response_Cardname   VARCHAR2(128);
    l_response_points   number;
    L_AMOUNT  NUMBER;
    data varchar2(32767);
    name  VARCHAR2(256);
    value VARCHAR2(1024);
    i number;

    l_nonce_raw   RAW (100);
    l_nonce_b64   VARCHAR2 (100);
    l_timestamp_char VARCHAR2(100)  := TO_CHAR(SYSTIMESTAMP,'YYYY-MM-DD"T"HH24:MI:SS.FF3"Z"');
    --'https://inatestgumrukws.unifree.com.tr/Services/CustomService.svc',
  BEGIN
    l_nonce_raw := UTL_I18N.string_to_raw (DBMS_RANDOM.string ('a', 16), 'utf8');
    l_nonce_b64 := TL_I18N.raw_to_char (UTL_ENCODE.base64_encode (l_nonce_raw), 'utf8');

    UTL_HTTP.SET_WALLET('file:/oracle/Certs/wallet', 'aiadmin123');
        --  show_html_from_url('https://inatestgumrukws.unifree.com.tr/Services/CustomService.svc');

  FOR FETCH_HEADER IN GET_HEADER LOOP 
  l_string_request := '<?xml version="1.0" encoding="UTF-8"?>
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="https://unifree.com.tr/services/custom" xmlns:cus1="http://schemas.datacontract.org/2004/07/CustomServiceLibrary.DataContract">

   <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" 
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
      xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-ABF79B0979E24BB376155515304061026" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-13">
      <wsse:Username>75</wsse:Username>
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Test357</wsse:Password>
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'||l_nonce_b64||'</wsse:Nonce>
      <wsu:Created>'||l_timestamp_char||'</wsu:Created>
      </wsse:UsernameToken></wsse:Security>
   </soapenv:Header>

   <soapenv:Body><cus:SaveSales><!--Optional:-->
    <cus:salesRequestENDataContract><cus1:Subcontractor>
    <cus1:CompanyCode>75</cus1:CompanyCode><cus1:RegionCode>98</cus1:RegionCode><cus1:StoreCode>UMT41</cus1:StoreCode>
    <cus1:CashTillCode>1</cus1:CashTillCode><cus1:CashierCode>'||FETCH_HEADER.CASH_NAT_ID||'</cus1:CashierCode></cus1:Subcontractor>
    <cus1:SalesDate><cus1:Day>'||FETCH_HEADER.GUN||'</cus1:Day><cus1:Month>'||FETCH_HEADER.AY||'</cus1:Month><cus1:Year>'||FETCH_HEADER.YIL||'</cus1:Year>
    <cus1:Hour>'||FETCH_HEADER.SAAT||'</cus1:Hour><cus1:Minute>'||FETCH_HEADER.DAKIKA||'</cus1:Minute><cus1:Second>'||FETCH_HEADER.SANIYE||'</cus1:Second>
    </cus1:SalesDate><!--Optional:--><cus1:InvoiceNumber>'||FETCH_HEADER.DOC_PROV_NO||'</cus1:InvoiceNumber><cus1:Customer>
    <cus1:IdentityType>'||FETCH_HEADER.DOC_TYPE||'</cus1:IdentityType><cus1:PassportNo>'||FETCH_HEADER.PASSPORT_NO||'</cus1:PassportNo>
    <cus1:CustomerName>'||FETCH_HEADER.PASS_SUR_NAME||'</cus1:CustomerName><cus1:DateOfBirth>
    <cus1:Day>'||TO_CHAR(FETCH_HEADER.PAS_DOB,'DD')||'</cus1:Day><cus1:Month>'||TO_CHAR(FETCH_HEADER.PAS_DOB,'MM')||'</cus1:Month>
    <cus1:Year>'||TO_CHAR(FETCH_HEADER.PAS_DOB,'YYYY')||'</cus1:Year><cus1:Hour>0</cus1:Hour><cus1:Minute>0</cus1:Minute>
    <cus1:Second>0</cus1:Second></cus1:DateOfBirth><cus1:PassengerTypeCode>'||FETCH_HEADER.PASSENGER_TYPE||'</cus1:PassengerTypeCode>
    <cus1:Arrival_Departure_Code>2</cus1:Arrival_Departure_Code></cus1:Customer><cus1:SalesLine><!--Zero or more repetitions:-->
    <cus1:SalesLine><cus1:ProductGroupCode>99</cus1:ProductGroupCode><cus1:SalesQuantity>'||FETCH_HEADER.SUM_QTY||'</cus1:SalesQuantity>
    <cus1:LimitUnitQuantity>'||FETCH_HEADER.SUM_QTY||'</cus1:LimitUnitQuantity><!--Optional:--><cus1:DolarAmount>'||FETCH_HEADER.TENDER_AMOUNT*1.12||'</cus1:DolarAmount>
    <!--Optional:--><cus1:EuroAmount>'||FETCH_HEADER.TENDER_AMOUNT||'</cus1:EuroAmount></cus1:SalesLine></cus1:SalesLine></cus:salesRequestENDataContract>
    </cus:SaveSales></soapenv:Body></soapenv:Envelope>';

   UTL_HTTP.set_response_error_check (TRUE);
   UTL_HTTP.set_detailed_excp_support (TRUE);
   UTL_HTTP.set_cookie_support (TRUE);
   UTL_HTTP.set_follow_redirect (3);
   UTL_HTTP.set_persistent_conn_support (TRUE);
   UTL_HTTP.SET_TRANSFER_TIMEOUT(200);

   l_http_request :=  UTL_HTTP.begin_request ('https://inatestgumrukws.unifree.com.tr/Services/CustomService.svc', 'POST', UTL_HTTP.HTTP_VERSION_1_1);

    --UTL_HTTP.SET_HEADER(l_http_request, 'User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)');
    UTL_HTTP.SET_HEADER(l_http_request, 'User-Agent', 'Mozilla/4.0');
  --  UTL_HTTP.set_header(l_http_request, 'Host', l_host_name || ':' || l_port);
    --UTL_HTTP.set_authentication(l_http_request,'75','Test357');
   -- UTL_HTTP.set_header(l_http_request, 'Connection', 'close');
    UTL_HTTP.set_header(l_http_request, 'Content-Type', 'text/xml;charset=UTF-8');
    UTL_HTTP.set_header(l_http_request, 'SOAPAction', 'https://unifree.com.tr/services/custom/ICustomServiceEN/SaveSales');
    UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_string_request));
    UTL_HTTP.write_text(l_http_request, l_string_request);
    DBMS_OUTPUT.put_line('Request>' || l_string_request || '');

    DBMS_OUTPUT.put_line('Response> content-length: "' || LENGTH(l_string_request) || '"');

  <<request_loop>>
    FOR i IN 0..CEIL(LENGTH(l_string_request) / l_buffer_size) - 1 LOOP

        l_substring_msg := SUBSTR(l_string_request, i * l_buffer_size + 1, l_buffer_size);

        BEGIN
            l_raw_data := utl_raw.cast_to_raw(l_substring_msg);
            UTL_HTTP.write_raw(r => l_http_request, data => l_raw_data);
            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    EXIT request_loop;
        END;
    END LOOP request_loop;


    l_http_response := UTL_HTTP.get_response(l_http_request);
    DBMS_OUTPUT.put_line('Response> status_code: "' || l_http_response.status_code || '"');
    DBMS_OUTPUT.put_line('Response> reason_phrase: "' ||l_http_response.reason_phrase || '"');
    DBMS_OUTPUT.put_line('Response> http_version: "' ||l_http_response.http_version || '"');


    IF l_http_response.status_code = '200' AND l_http_response.reason_phrase = 'OK' THEN
            --null;
    UPDATE OFF_SENT_SALES@MOSIAT
    SET SENT_FLAG = 9
    WHERE SALE_REF_NO = FETCH_HEADER.SALE_REF_NO
    AND DOC_PROV_NO = FETCH_HEADER.TRANSNUMBER;

    END IF;

   BEGIN

        <<response_loop>>
        LOOP
            UTL_HTTP.read_raw(l_http_response, l_raw_data, l_buffer_size);
            l_clob_response := l_clob_response || UTL_RAW.cast_to_varchar2(l_raw_data);
        END LOOP response_loop;

        EXCEPTION
            WHEN UTL_HTTP.end_of_body THEN
                UTL_HTTP.end_response(l_http_response);
    END;    


    DBMS_OUTPUT.put_line('Response> length: "' || LENGTH(l_clob_response) || '"');
   -- DBMS_OUTPUT.put_line('Response> ' || (l_clob_response) || '"');
    DBMS_OUTPUT.put_line(CHR(10) || '=== Print first ' || l_lines_count || ' lines of HTTP response... ===' || CHR(10) || CHR(10));


    FOR i IN 0..CEIL(LENGTH(l_clob_response) / l_line_size) - 1 LOOP
        l_line := SUBSTR(l_clob_response, i * l_line_size + 1, l_line_size);
        DBMS_OUTPUT.put_line('[' || LPAD(i, 2, '0') || ']: ' || l_line);
        EXIT WHEN i > l_lines_count - 1;
    END LOOP print_response;


  IF l_http_request.private_hndl IS NOT NULL THEN
        UTL_HTTP.end_request(l_http_request);
    END IF;

    IF l_http_response.private_hndl IS NOT NULL THEN
        UTL_HTTP.end_response(l_http_response);
    END IF;

    end loop;


    UTL_HTTP.end_response(l_http_response);

      commit;


   END   SALES_XML_CUSTOMS_PRC; 

我总是得到以下错误

5:26:00 PM  ORA-29269: HTTP server error 500 - Internal Server Error
5:26:00 PM  ORA-06512: at "SYS.UTL_HTTP", line 1367
5:26:00 PM  ORA-06512: at "INVSPROD.SALES_XML_CUSTOMS_PRC_5", line 155
5:26:00 PM  ORA-06512: at line 7

标签: oraclesoapplsql

解决方案


您可以使用商业ORA_XML包添加 UserToken 标头:

DECLARE
  encode_password BOOLEAN; 
  signed_soap CLOB;
  soap_data CLOB;
BEGIN
    soap_data := '...';
 
    encode_password := FALSE; 
 
    signed_soap := ORA_XML.SOAP_WSS_USERNAME_SIGN(soap_data, 'user', 'pass', encode_password);
 
    DBMS_OUTPUT.put_line('signed_data=' || signed_soap);
END;

免责声明:我在滴滴软件工作


推荐阅读