Delphi soap https身份验证失败将弹出一个对话框

Delphi soap https身份验证失败将弹出一个对话框,delphi,soap,wininet,Delphi,Soap,Wininet,我们有一个delphi XE应用程序,它使用SOAP(THTTPRIO等)通信(在delphi中)在默认情况下通过WinInet.dll工作。我们修复了身份验证代码,使用https身份验证使其正常工作,当https的用户名和密码正确时,一切正常 问题是,当身份验证详细信息不正确时,您会从Windows获得一个消息框,WinInet.dll本身可能会弹出该消息框。我想让那个对话框消失。我不知道如何更改我的Delphi SOAP,这样密码就不会出现 情况如下: 我正在做他正在做的所有事情,包括调用I

我们有一个delphi XE应用程序,它使用SOAP(THTTPRIO等)通信(在delphi中)在默认情况下通过WinInet.dll工作。我们修复了身份验证代码,使用https身份验证使其正常工作,当https的用户名和密码正确时,一切正常

问题是,当身份验证详细信息不正确时,您会从Windows获得一个消息框,WinInet.dll本身可能会弹出该消息框。我想让那个对话框消失。我不知道如何更改我的Delphi SOAP,这样密码就不会出现

情况如下:

  • 我正在做他正在做的所有事情,包括调用InternetSetOption(…)来设置用户名和密码

  • 我没有使用具有自签名证书的服务器,因此soIgnoreInvalidCerts标志不适用于我的情况

  • 不知何故,我认为我需要对WinInet进行一些API调用,告诉它不要弹出它的
    InternetErrorDlg
    (某些版本的windows称为windows安全选项),以询问用户

  • 在我的例子中,配置文件中的用户名和密码被使用,它是错误的(过期),因此我们希望WinInet代码只返回一个错误,而不是弹出对话框

  • 也许另一个问题是这个家伙确实知道如何做到这一点,但这个问题的细节不足以说明他是如何做到的。被接受的答案对我不适用

    我遵循的一些死胡同:

    WinInet MSDN文档用于
    插件\u身份验证\u标志\u可处理\u 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;
    
    过程TMyDevice.HTTPWebNodeOnBeforePost(
    常量HTTPReqResp:SOAPHTTPTrans.THTTPReqResp;数据:指针);
    变量
    安全标志:德沃德;
    安全标志:德沃德;
    开始
    {身份验证,NTLM+HTTPS,通过WinInet设置INTERNET选项API设置WinInet身份验证。
    建议在新闻组上使用此方法进行https基本身份验证。}
    如果fUserName“”那么
    如果不是InternetSetOption(数据,
    INTERNET\u选项\u用户名,
    PChar(fUserName),
    长度(fUserName))那么
    引发EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError));
    如果fPassword“”那么
    如果不是InternetSetOption(数据,
    INTERNET\u选项\u密码,
    PChar(fPassword),
    长度(fPassword))然后
    引发EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError));
    {可能的黑客行为类型:停止密码框的WinInet安全选项标志?}
    SecurityFlagsLen:=SizeOf(SecurityFlags);
    InternetQueryOption({Request}数据、INTERNET选项、安全标志、,
    指针(@SecurityFlags),SecurityFlagsLen);
    SecurityFlags:=SecurityFlags或SECURITY\u FLAG\u某物;
    InternetSetOption({Request}数据、INTERNET选项、安全标志、,
    指针(@SecurityFlags),SecurityFlagsLen);
    结束;
    

    此代码使密码有效,但当用户输入的密码错误时,如何使SOAP调用失败或引发异常,而不是弹出消息框?

    尝试修改SOAPHTTPTrans以静默方式处理错误。 在THTTPReqResp.HandleWinInetError中,最终会调用错误对话框:

      Result := CallInternetErrorDlg
    

    您可能可以检测到您的特定错误,您应该能够从HandleWinInetError返回0,或者至少不调用CallInternetErrorDlg。看看这是否有帮助。

    用WinHTTP组件替换WinINet。两者都有非常接近的API,第二个API不会创建任何UI交互,但会像其他API一样返回错误代码。WinINet的UI部分对于某些软件来说可能是个好主意,但听起来似乎不适合您的需要

    当然,HTTPS和身份验证将以类似的方式处理。但是您必须提示输入用户名和密码,并根据请求更新HTTP头。看

    根据我们的测试,WinHTTP比WinINet快得多(当然是因为它没有实现任何UI部分,也没有链接到Internet Explorer库)


    您可以看看WinINet和WinHTTP之间的API差异有多小(大多数代码在链接单元中共享)

    您是否尝试在
    INTERNET\u选项\u ERROR\u MASK
    中设置该标志?该标志会添加一个额外的错误报告,但不会删除一个。有趣的是,WinInet.pas中没有定义该代码。该代码没有被调用,我也不知道为什么。此外,某些计算机(对话框从不出现)和某些计算机(对话框总是出现)之间也存在差异。我怀疑WinInet内部有一个很深的怪癖。是否所有(您正在测试的)计算机都有相同版本的Internet Explorer?这决定了您拥有哪个WinInet DLL。奇怪的是,所有的计算机都有IE 8.0,有些是XP,有些是Win7,而且似乎XP计算机是不同的。不要修改oem源,只需将
    OnWinInetError
    处理程序分配给
    THTTPReqResp
    实例。我们必须自定义RTL SOAP代码以使用WinHTTP,我想是吧。或者干脆重写WinINet using类来代替WinHTTP API?沃伦P:你是如何使用WinHTTP的?