2011-11-18 7 views
7

Mamy aplikację delphi XE, która używa komunikacji SOAP (THTTPRIO itp.), Która (w delphi) działa domyślnie nad WinInet.dll. Naprawiliśmy kod uwierzytelniający, aby działał, używając uwierzytelniania https, a gdy nazwa użytkownika i hasło dla https są poprawne, wszystko jest w porządku.Usterka uwierzytelniania Delphi https wyskakuje okno dialogowe

Problem polega na tym, że gdy dane uwierzytelniające są niepoprawne, pojawia się okno komunikatu z systemu Windows, które prawdopodobnie pojawiło się w samym WinInet.dll. Chcę, aby to okno dialogowe zniknęło. Nie mogę wymyślić, jak zmienić moje SOAP Delphi, aby hasło nie pojawiło się.

Sytuacja jest different than this question w jeden z następujących sposobów:

  1. Robię wszystko, co robi, w tym powołanie InternetSetOption (...), aby ustawić nazwę użytkownika i hasło.

  2. Nie używam serwera z samopodpisanym certyfikatem, więc flaga soIgnoreInvalidCerts nie ma zastosowania w moim przypadku.

  3. Jakoś myślę, że trzeba uzyskać niektóre API stawia pod WinInet, aby poinformować go, aby nie pop-up InternetErrorDlg że ma (niektóre wersje Windows powiedzieć Opcje zabezpieczeń systemu Windows), które pojawia się zadać użytkownikowi.

  4. W moim przypadku nazwa użytkownika i hasło, które mamy w naszym pliku konfiguracyjnym są używane, są błędne (nieaktualne) i dlatego chcemy, aby kod WinInet po prostu wyświetlał błąd zamiast pojawiać się w oknie dialogowym .

Być może inne pytanie facet naprawdę wymyślił, jak to zrobić, ale szczegóły na to pytanie są niewystarczające, aby zobaczyć, jak to zrobił. Przyjęta odpowiedź nie działa dla mnie.

Niektóre martwe końce Mam następuje:

WinInet MSDN docs dla PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI - że nie wydaje się mieć zastosowanie do użytkownika WinInet, raczej do wtyczki.

WinInet MSDN docs dyskutować InternetSetOption, a niektóre grupy mają doprowadzić mnie do następującego kodu on-przed-post obsługi zdarzenia:

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; 

Kod ten sprawia, że ​​praca hasła, ale gdy wprowadzone hasło użytkownika jest nieprawidłowa , w jaki sposób uzyskać wywołanie SOAP, aby niepowodzenie, lub podnieść wyjątek, zamiast pojawiać się okno komunikatu?

+0

Czy spróbować ustawienie [ '] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa385328 INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY' (v = vs.85 .aspx)) flagi' INTERNET_OPTION_ERROR_MASK' ? –

+0

Ta flaga dodaje dodatkowy raport o błędzie, ale nie usuwa go. Co ciekawe, nie jest to zdefiniowane w WinInet.pas. –

Odpowiedz

2

Zastąp winINet elementem WinHTTP. Oba mają bardzo bliskie API, a druga nie tworzy żadnej interakcji UI, ale zwraca kody błędów, tak jak każdy inny API. Część interfejsu użytkownika WinINet może być dobrym pomysłem dla niektórych programów, ale brzmi, jakby nie pasowała do twoich potrzeb.

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

Oczywiście, HTTPS i autoryzacji będą przetwarzane w podobny sposób. Musisz jednak podać nazwę użytkownika i hasło, a następnie zaktualizować nagłówki HTTP zgodnie z wymaganiami. Zobacz this link.

Z naszych testów WinHTTP jest znacznie szybszy niż WinINet (z pewnością dlatego, że nie implementuje żadnej części interfejsu użytkownika i nie jest powiązany z bibliotekami Internet Explorer).

Możesz przyjrzeć się our Open Source classes, aby odgadnąć, jak mała jest różnica w API między WinINet i WinHTTP (większość kodu jest udostępniana w połączonej jednostce).

+0

Będziemy musieli niestandardowo zhakować kod SOAP RTL, aby użyć WinHTTP, jak sądzę. –

+0

Lub po prostu zastąpić WinINet używając klasy do używania API WinHTTP zamiast? –

0

Spróbuj zmodyfikować SOAPHTTPTrans, aby działał po cichu. W THTTPReqResp.HandleWinInetError, jest ostatecznie wezwaniem do dialogu o błędzie:

Result := CallInternetErrorDlg 

Prawdopodobnie można wykryć szczególną błąd, powinieneś być w stanie powrócić do 0 z HandleWinInetError, albo przynajmniej nie zatelefonować do CallInternetErrorDlg. Sprawdź, czy to pomaga.

+0

Ten kod nie jest wywoływany i nie wiem, dlaczego. Istnieje również różnica między niektórymi komputerami (gdzie okno dialogowe nigdy nie pojawia się) i niektórymi komputerami (gdzie zawsze pojawia się). Podejrzewam głębokie dziwactwo w WinInet. –

+0

Czy wszystkie komputery (na których testujesz) mają tę samą wersję przeglądarki Internet Explorer? To określa, która WinInet DLL posiadasz. –

+0

Dziwne, wszystkie komputery mają IE 8.0, niektóre są XP, a niektóre Win7 i wygląda na to, że komputery XP są inne. –