Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 windows авторизация для вызова веб-сервиса  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54384
надо из линухового оракла вызвать веб-сервис, а там стоит windows-авторизация
    v_req := utl_http.begin_request(v_service_URL, 'POST','HTTP/1.1');
              
    UTL_HTTP.set_authentication(v_req, 'domain\username', 'mypwd', 'Basic', FALSE); -- true for proxy 
    utl_http.set_header(v_req, 'Content-Type', 'text/xml;  charset=utf-8');
    utl_http.set_header(v_req, 'Content-Length', LENGTH(v_xmlRequest));
    utl_http.set_header(v_req, 'SOAPAction', '/api/values');
    utl_http.write_text(v_req, v_xmlRequest);
    dbms_output.put_line('start get_response', TRUE);
    v_resp := utl_http.get_response(v_req);
    V_status_code := v_resp.status_code;
    dbms_output.put_line('HTTP response: ' || v_resp.status_code || ' (' || v_resp.reason_phrase || ')', TRUE);

выдает
401 (Unauthorized)

чё делать, куда рыть
13 июн 18, 12:30    [21487967]     Ответить | Цитировать Сообщить модератору
 Re: windows авторизация для вызова веб-сервиса  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54384
12 лет назад написали, что нельзя
2770620
13 июн 18, 12:38    [21488005]     Ответить | Цитировать Сообщить модератору
 Re: windows авторизация для вызова веб-сервиса  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 9254
Была проблема, что нужна была Windows авторизация на офисную проксю, решал с помощью Chtlm.
Можно ли через Chtlm авторизоваться на конечном сервере/веб-службе, не знаю.

надеюсь http://cntlm.sourceforge.net/ но сейчас весь сайт на мейтенансе, т.ч. адрес мне не проверить.
13 июн 18, 12:57    [21488106]     Ответить | Цитировать Сообщить модератору
 Re: windows авторизация для вызова веб-сервиса  [new]
Vadim Lejnin
Member

Откуда:
Сообщений: 7134
Смотря что тебе от службы нужно
посмотри вот это:
NTLM for PL/SQL
13 июн 18, 13:18    [21488161]     Ответить | Цитировать Сообщить модератору
 Re: windows авторизация для вызова веб-сервиса  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54384
Vadim Lejnin
Смотря что тебе от службы нужно
посмотри вот это:
NTLM for PL/SQL
передать туда файл
и получить оттуда файл
13 июн 18, 13:38    [21488230]     Ответить | Цитировать Сообщить модератору
 Re: windows авторизация для вызова веб-сервиса  [new]
MazoHist
Member

Откуда:
Сообщений: 145
Для всех тех, кто столкнулся с той же задачей что и ТС - может кому-то сэкономит время. По ссылке можно найти пакеты для авторизации NTLM и работы по http (сейчас они входят в состав alexandria-plsql-utils, там есть обертка для работы по методу GET, но для SOAP требуется POST, с которым есть нюансы. Привожу код, с которым у меня все заработало.
+ простыня кода

declare
  cURL constant varchar2(160):='http://iis-test.local/FinReportWebService/FinReport.asmx';
  cSoapText constant varchar2(2000) :=
  '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:asmx="http://asmx.service.local/">
   <soapenv:Header/>
   <soapenv:Body>
      <asmx:GetReport>
        <asmx:arg>
            <asmx:ReportID>1</asmx:ReportID>
         </asmx:arg>
      </asmx:GetReport>
   </soapenv:Body>
</soapenv:Envelope>';
  cAction constant varchar2(100) := '"http://asmx.service.local/GetReport"';
  vSoapResp clob;
  vRespBuf varchar2(32767);

  http_req  utl_http.req;
  http_resp utl_http.resp;

  l_authenticate_with_ntlm       boolean;

  l_name                         varchar2(500);
  l_value                        varchar2(500);

  l_ntlm_message                 varchar2(500);

  l_negotiate_message            varchar2(500);

  l_server_challenge             raw(4000);
  l_negotiate_flags              raw(4000);

  l_authenticate_message         varchar2(500);

  l_username  varchar2(500) := 'DOMAIN\user'; --имя домена в uppercase
  l_password  varchar2(500) := 'Password';

  procedure debug_response (p_resp in out utl_http.resp)
  as
    l_name  varchar2(255);
    l_value varchar2(2000);
    l_body  clob;
  begin

    debug_pkg.printf('Response Status Code: %1', p_resp.status_code);

    for i in 1 .. utl_http.get_header_count (p_resp) loop
      utl_http.get_header (p_resp, i, l_name, l_value);
      debug_pkg.printf('#%1 %2 : %3', i, l_name, l_value);
    end loop;

    --debug_pkg.printf('Body length = %1', dbms_lob.getlength (l_returnvalue));
    debug_pkg.printf('Persistent connection count: %1', utl_http.get_persistent_conn_count);

  end debug_response;

begin
  debug_pkg.debug_on;

  utl_http.set_detailed_excp_support (enable => true);
  utl_http.set_response_error_check  (enable => false);

  utl_http.set_persistent_conn_support (true, 10);

  debug_pkg.printf(' ');
  debug_pkg.printf(curl);

  http_req:= utl_http.begin_request(cURL, 'HEAD','HTTP/1.1');
  utl_http.set_body_charset(http_req, 'UTF-8');

  utl_http.set_header(http_req, 'Content-Type', 'text/xml');
  utl_http.set_header(http_req, 'SOAPAction', cAction);
  utl_http.set_header(http_req, 'Content-Length', length(cSoapText));
  utl_http.set_header(http_req, 'Connection', 'Keep-Alive');
  utl_http.write_text(http_req, cSoapText);
  http_resp := utl_http.get_response(http_req);

  if http_resp.status_code = utl_http.HTTP_UNAUTHORIZED then
    utl_http.end_response (http_resp);

    l_negotiate_message := 'NTLM ' || ntlm_util_pkg.get_negotiate_message(l_username);
    -- need to send negotiation message

    debug_pkg.printf('Negotiate message: %1', l_negotiate_message);

    debug_pkg.printf(' ');
    debug_pkg.printf(curl);
    http_req:= utl_http.begin_request(cURL, 'HEAD','HTTP/1.1');
    utl_http.set_body_charset(http_req, 'UTF-8');
    utl_http.set_header(http_req, 'Content-Type', 'text/xml');
    utl_http.set_header(http_req, 'SOAPAction', cAction);
    utl_http.set_header(http_req, 'Content-Length', length(cSoapText));
    utl_http.set_header(http_req, 'Connection', 'Keep-Alive');
    utl_http.set_header(http_req, 'Authorization', l_negotiate_message);
    utl_http.write_text(http_req, cSoapText);
    http_resp := utl_http.get_response(http_req);
    if http_resp.status_code = utl_http.HTTP_UNAUTHORIZED then
      -- received server challenge
      utl_http.get_header_by_name(http_resp, 'WWW-Authenticate', l_value, 1);
      utl_http.end_response(http_resp);

      if substr(l_value, 1, 4) = 'NTLM' then
        l_value := substr(l_value, 6);
        ntlm_util_pkg.parse_challenge_message (l_value, l_server_challenge, l_negotiate_flags);

        l_authenticate_message := 'NTLM ' || ntlm_util_pkg.get_authenticate_message(l_username, l_password, l_server_challenge, l_negotiate_flags);
        debug_pkg.printf('Authenticate message: "%1"', l_authenticate_message);

        http_req:= utl_http.begin_request(cURL, 'POST','HTTP/1.1');
        utl_http.set_body_charset(http_req, 'UTF-8');
        utl_http.set_header(http_req, 'Content-Type', 'text/xml;charset=UTF-8');
        utl_http.set_header(http_req, 'SOAPAction', cAction);
        utl_http.set_header(http_req, 'Content-Length', length(cSoapText));
        utl_http.set_header(http_req, 'Connection', 'Close');
        utl_http.set_header(http_req, 'Authorization', l_authenticate_message);
        utl_http.write_text(http_req, cSoapText);
        http_resp := utl_http.get_response(http_req);
      end if;
    end if;
  end if;

  begin
    loop
       utl_http.read_text(http_resp,vRespBuf,32767);
       vSoapResp:=vSoapResp||vRespBuf;
    end loop;
  exception
    when utl_http.end_of_body then
      utl_http.end_response (http_resp);
  end;

  for i in 1..trunc(dbms_lob.getlength(vSoapResp)/256) loop
    dbms_output.put_line(dbms_lob.substr(vSoapResp, 256, 256*(i-1)+1));
  end loop;
  dbms_output.put_line(dbms_lob.substr(vSoapResp, 256, trunc(dbms_lob.getlength(vSoapResp)/256)*256+1));
end;


Нюанс в том, что NTLM требует неразрывного соединения (persistent), а POST из Oracle так не умеет. Workaround - использовать в запросах на NTLM challenge метод HEAD.
14 май 19, 15:17    [21884527]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить