Как остановить появление диалогового окна аутентификации при использовании THTTPRIO

Я подключаюсь к веб-службе, используя базовую проверку подлинности, используя следующий код:

var
  RIO: THTTPRIO;
begin
  RIO := THTTPRIO.Create(nil);

  EndPoint := GetWebServicePort(True, '', RIO);

  RIO.HTTPWebNode.UserName := 'xxxx';
  RIO.HTTPWebNode.Password := 'yyyy';
...
end;

Если имя пользователя и пароль верны, все работает нормально. Однако, если они неверны, появится диалоговое окно Windows с запросом правильных учетных данных. Вместо диалога мне нужно отловить ошибку.

введите описание изображения здесь

Как мне остановить всплывающее диалоговое окно? Я искал и нашел несколько результатов (Ссылка 1, Ссылка 2), но ни один из них не предлагает реального решения.


person norgepaul    schedule 23.02.2015    source источник
comment
Это старая нерешенная ошибка в компоненте THttpRio. Используйте вместо Indy   -  person RBA    schedule 23.02.2015
comment
Это связано с тем, что реализация веб-службы в Delphi использует неправильный Windows API - используя WinInet вместо WinHTTP. Как явно указано в MSDN (msdn .microsoft.com / en-us / library / windows / desktop /), WinINet отображает пользовательский интерфейс для некоторых операций, таких как сбор учетных данных пользователя. Однако WinHTTP выполняет эти операции программно. Это также очень опасно, потому что, если вы используете его в службе, служба может зависнуть в ожидании ввода пользователя, который никогда не может быть введен, потому что диалоговое окно не отображается на любом рабочем столе, доступном для пользователя.   -  person LDS    schedule 23.02.2015
comment
Не уверен, что это полезно, потому что я сам не пробовал и не уверен, что это остановит Windows диалог, но, может быть, обработчик событий HTTPRIO.HTTPWebNode.OnWinInetError может пригодиться? Вам нужно будет проверить наличие ошибки HTTP_STATUS_PROXY_AUTH_REQ.   -  person Guillem Vicens    schedule 23.02.2015
comment
Обратите внимание, что похоже, что вы можете использовать WinHTTP с Delphi SOAP: см. stackoverflow.com/questions/26911550/   -  person mjn    schedule 23.02.2015
comment
@mjn - даже после определения USE_INDY диалоговое окно все еще появляется.   -  person norgepaul    schedule 23.02.2015


Ответы (1)


Чтобы поймать ошибку, вы можете использовать клиентскую библиотеку HTTP, например Indy TIdHTTP, чтобы сначала запустить HTTP-запрос GET (или HEAD) на адрес веб-службы и перехватить исключение, которое выдается, когда пользователь / пароль неверны.

uses
  ... IdHTTP ...;

...
var
  HTTP: TIdHTTP;

ValidCredentials := False;
...    
HTTP.Request.Username := username;
HTTP.Request.Password := password;
HTTP.Request.BasicAuthentication := True;
try
  HTTP.Head(url);
  ValidCredentials := HTTP.ResponseCode = 200;
except
  on ... (some Indy exception) do
  begin
    // signal that username / password are incorrect
    ...
  end;
end;

if ValidCredentials then
begin
  // invoke Web Service ...
person mjn    schedule 23.02.2015
comment
Хотя это решение будет работать, оно похоже на взлом. Нужно ли нам перед каждым подключением указывать приведенный выше код или делать это один раз и надеяться, что учетные данные не изменятся после первоначальной проверки? Однако, поскольку ни один из других вариантов, похоже, не работает, это может быть нашим единственным шансом. Спасибо, mjn! - person norgepaul; 23.02.2015