Delphi мыло https ошибка аутентификации всплывает диалоговое окно - PullRequest
7 голосов
/ 18 ноября 2011

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

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

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

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

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

  3. Каким-то образом я думаю, что мне нужно получить некоторые вызовы API в WinInet, чтобы запретить емувсплывающее InternetErrorDlg, которое у него есть (некоторые версии окон говорят, что параметры безопасности 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 ]

2 голосов
/ 18 ноября 2011

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

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

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

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

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

0 голосов
/ 18 ноября 2011

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

  Result := CallInternetErrorDlg

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

...