Delphi soap https ошибка аутентификации всплывает диалоговое окно

У нас есть приложение delphi XE, которое использует SOAP (THTTPRIO и т. д.), которое (в delphi) работает над WinInet.dll, по умолчанию. Мы исправили код аутентификации, чтобы он работал, используя аутентификацию https, и когда имя пользователя и пароль для https верны, все в порядке.

проблема в том, что когда данные аутентификации неверны, вы получаете окно сообщения из Windows, которое, вероятно, появляется WinInet.сама библиотека dll. Я хочу сделать это диалоговое окно go away. Я не могу понять, как изменить мое мыло Delphi, чтобы пароль не появился.

ситуация отличается от этого вопроса следующим образом:

  1. Я делаю все, что он делает, включая вызов InternetSetOption(...) установить имя пользователя и пароль.

  2. Я не использую сервер с самозаверяющим сертификатом, поэтому флаг soIgnoreInvalidCerts неприменим к моему делу.

  3. Так или иначе, я думаю, что мне нужно получить некоторые вызовы API в WinInet, чтобы сказать ему не всплывать InternetErrorDlg что у него есть (некоторые версии windows говорят параметры безопасности Windows), которые появляются, чтобы спросить пользователя.

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

возможно, другой вопрос, что парень действительно понял, как это сделать, но детали по этому вопросу недостаточны, чтобы увидеть, как он это сделал. Принятый ответ не работает для меня.

некоторые тупики я следовал:

документы WinInet MSDN для PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI - это, по-видимому, не применимо к пользователю WinInet, а к плагину.

документы WinInet MSDN обсуждают InternetSetOption, и некоторые группы новостей привели меня к следующий код обработчика событий перед отправкой:

procedure TMyDevice.HTTPWebNodeOnBeforePost(
  const HTTPReqResp: SOAPHTTPTrans.THTTPReqResp; Data: Pointer);
var
 SecurityFlagsLen:DWORD;
 SecurityFlags:DWORD;
begin
  { authentication, NTLM+HTTPS, WinInet authentication set via WinInet SET INTERNET OPTION API.
    This approach recommended on newsgroups for https basic authentication.  }

    if fUserName<>'' then
   if not InternetSetOption(Data,
               INTERNET_OPTION_USERNAME,
               PChar(fUserName),
               Length(fUserName)) then
     raise EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError));

   if fPassword<>'' then
  if not InternetSetOption(Data,
               INTERNET_OPTION_PASSWORD,
               PChar(fPassword),
               Length (fPassword)) then
     raise EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError));

      { possible type of hackage: WinInet Security option flags to stop password box? }
     SecurityFlagsLen := SizeOf(SecurityFlags);
      InternetQueryOption({Request}data, INTERNET_OPTION_SECURITY_FLAGS,
      Pointer(@SecurityFlags), SecurityFlagsLen);
      SecurityFlags := SecurityFlags or SECURITY_FLAG_something;
      InternetSetOption({Request}data, INTERNET_OPTION_SECURITY_FLAGS,
      Pointer(@SecurityFlags), SecurityFlagsLen);
end;

этот код заставляет пароль работать, но когда введенный пароль пользователя неверен, как я могу получить сбой вызова SOAP или вызвать исключение, вместо того, чтобы выскакивать окно сообщения?

2 ответов


замените WinINet компонентом WinHTTP. Оба имеют очень близкие API, и 2nd не создает никакого взаимодействия с UI, но возвращает коды ошибок, как и любой другой API. Часть пользовательского интерфейса WinINet может быть хорошей идеей для некоторых программ, но похоже, что if не соответствует вашим потребностям.

см http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs. 85).aspx

конечно, HTTPS и аутентификация будут обрабатываться аналогичным образом. Но вам нужно будет запросить имя пользователя и пароль и обновить заголовки HTTP по запросу. См.этой ссылке.

из наших тестов WinHTTP намного быстрее, чем WinINet (конечно, потому, что он не реализует какую-либо часть пользовательского интерфейса и не связан с библиотеками Internet Explorer).

вы можете взглянуть на наши классы с открытым исходным кодом угадать, насколько мала разница в API между WinINet и WinHTTP (большинство кода совместно используется в связанном блок.)


попробуйте изменить SOAPHTTPTrans для обработки ошибки молча. В THTTPReqResp.HandleWinInetError, в конечном счете, есть вызов диалогового окна ошибки:

  Result := CallInternetErrorDlg

вероятно, вы можете обнаружить свою конкретную ошибку, вы должны иметь возможность вернуть 0 из HandleWinInetError или, по крайней мере, не звонить в CallInternetErrorDlg. Посмотрим, поможет ли это.