Как предотвратить диалоговое окно (запрос базовой аутентификации) во время вызова веб-сервиса

В программе Delphi (работающей как служба) мне нужно вызвать некоторые веб-службы.
Вызовы работают нормально, если не требуется базовая аутентификация. Вызовы также работают нормально, если требуется базовая аутентификация и предоставляется имя пользователя/пароль (в BeforePost), используя:

InternetSetOption(Data, INTERNET_OPTION_USERNAME,...
InternetSetOption(Data, INTERNET_OPTION_PASSWORD,...

Но если запрашивается базовая аутентификация, а имя пользователя/пароль не предоставлены, программа выводит подсказку для имени пользователя/пароля (это недопустимо в сервисе).

Итак, как я могу сигнализировать, что мне НЕ нужно приглашение, а вместо этого ошибка?

Проблема, как я понимаю, в функции SOAPHTTPTrans THTTPReqResp.Send(const ASrc: TStream): Integer; (строка 762 (второй вызов InternetErrorDlg в этом методе)).

EDIT1:
если я изменю флаги в начале метода отправки (в SOAPHTTPTRANS), чтобы включить INTERNET_FLAG_NO_AUTH, он будет работать так, как я хотел.
Но как мне это сделать, не меняя SAOPHTTPTrans (если возможно)?

EDIT2:

ws := THTTPRIO.Create(Self);
ws.URL := 'http://excample.com/ws.asmx';
ws.HTTPWebNode.InvokeOptions := [soIgnoreInvalidCerts];
ws.HTTPWebNode.OnBeforePost := WebServiceCallBeforePost;
AvailabilityWebservice := (ws as AvailabilityServiceSoap);
sTemp := AvailabilityWebservice.GetVersion;

Где AvailabilityServiceSoap — это интерфейс, созданный с помощью средства импорта WSDL.


person BennyBechDk    schedule 18.02.2010    source источник
comment
Разве вы не можете запустить свой сервис без взаимодействия с рабочим столом? Это может превратить текущее поведение в ошибку.   -  person Jeroen Wiert Pluimers    schedule 18.02.2010
comment
Как вы используете объект THTTPReqResp? как часть TSOAPConnection?   -  person James Barrass    schedule 18.02.2010
comment
Jeroen: Я еще не пробовал, но проблема в том, что запас процесса ожидает ввода, поэтому он висит.   -  person BennyBechDk    schedule 18.02.2010


Ответы (3)


Вы можете создать новый класс, который наследуется от THTTPReqResp, и переопределить метод отправки, чтобы вы могли включать свои собственные флаги. Вы должны иметь возможность установить ws.HTTPWebNode на новый узел, используя новый класс.

Что-то типа

ws := THTTPRIO.Create(Self);
MyNewNode := MyNewClass.Create;
ws.HTTPWebNode := MyNewNode;
ws.URL := 'http://excample.com/ws.asmx';
ws.HTTPWebNode.InvokeOptions := [soIgnoreInvalidCerts];
ws.HTTPWebNode.OnBeforePost := WebServiceCallBeforePost;
AvailabilityWebservice := (ws as AvailabilityServiceSoap);
sTemp := AvailabilityWebservice.GetVersion;
person James Barrass    schedule 18.02.2010
comment
Это похоже на работоспособное решение, мне просто не нравится копировать 170 строк из THTTPReqResp.Send . Так что, если есть какой-то способ добиться этого, не копируя этот код, он кажется лучше. - person BennyBechDk; 18.02.2010
comment
Я пытался скопировать метод Send в свой собственный объект, но использовалось много частных переменных. Так что заставьте его работать, весь блок должен быть скопирован и изменен. - person BennyBechDk; 22.02.2010
comment
Что происходит в onbeforepost? Поскольку вы показываете это, и поскольку я знаю, что вам, вероятно, нужно вызвать InternetSetOption там, было бы лучше, если бы он показал это. - person Warren P; 18.11.2011

У меня была эта проблема, когда я пытался разрешить Windows Live Messenger работать через веб-фильтр.

В итоге я написал небольшую программу, которая периодически выполняет автоматическую аутентификацию.

Надеюсь, это поможет и вам.

uses
  ... IdHTTP ...;

...
var
  httpGetter: TIdHTTP;
...    
httpGetter.Request.Username := username;
httpGetter.Request.Password := password;
httpGetter.HandleRedirects := True;
httpGetter.Request.BasicAuthentication := True;

//custom useragent required to let live messenger work
//this part is probably not necessary for your situation
httpGetter.Request.UserAgent := 'MSN Explorer/9.0 (MSN 8.0; TmstmpExt)';

httpGetter.Get(url,MS);
...
person JosephStyons    schedule 18.02.2010
comment
Это не решает проблему. Проблема в том, что когда логин и пароль НЕ введены, программа выводит подсказку af ждет (и работает как сервис на необслуживаемом сервере, это не бог). Я буду рад получить ошибку и обработать ее, как и любую другую ошибку. - person BennyBechDk; 18.02.2010

Как насчет того, чтобы сначала проверить режим аутентификации серверов?

http://en.wikipedia.org/wiki/Basic_access_authentication

  • Клиент запрашивает страницу, которая требует аутентификации, но не предоставляет имя пользователя и пароль. Обычно это происходит потому, что пользователь просто ввел адрес или перешел по ссылке на страницу.
  • Сервер отвечает кодом ответа 401 и предоставляет область аутентификации.

Таким образом, приложение клиентской службы может отправить Get и посмотреть, есть ли в ответе заголовок, например

WW-Authenticate: Basic realm="Secure Area"
person mjn    schedule 18.02.2010