我们有一个使用SOAP(THTTPRIO等)通信的delphi XE应用程序,默认情况下(在delphi中)通过WinInet.dll工作。我们使用https身份验证修复了身份验证代码以使其正常工作,并且当https的用户名和密码正确时,一切正常。
问题是,当身份验证详细信息不正确时,您会从Windows获得一个消息框,这可能是由WinInet.dll本身弹出的。我想让那个对话框消失。我无法弄清楚如何更改我的Delphi SOAP,因此密码不会出现。
情况如下different than this question:
我正在做他正在做的所有事情,包括调用InternetSetOption(...)来设置用户名和密码。
我没有使用带有自签名证书的服务器,所以soIgnoreInvalidCerts标志不适用于我的情况。
不知何故,我想我需要在WinInet中调用一些API来告诉它不要弹出它所拥有的InternetErrorDlg
(某些版本的Windows称Windows安全选项)弹出来询问用户。
在我的情况下,我们在配置文件中使用的用户名和密码正在使用,这是错误的(过时的),因此我们希望WinInet代码只返回错误而不是弹出对话框框。
也许这个家伙确实知道如何做到这一点的另一个问题,但这个问题的细节不足以看出他是如何做到的。接受的答案对我不起作用。
我遵循的一些死胡同:
PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI
的WinInet MSDN文档 - 似乎不适用于WinInet用户,而是适用于插件。
WinInet MSDN文档讨论了InternetSetOption,一些新闻组引导我进入以下on-before-post事件处理程序代码:
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调用失败或引发异常,而不是弹出消息框?
答案 0 :(得分:2)
用WinHTTP组件替换WinINet。两者都有非常接近的API,第二个不会创建任何UI交互,但会返回错误代码,就像任何其他API一样。对于某些软件,WinINet的UI部分可能是一个好主意,但听起来好像不符合您的需求。
请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs.85).aspx
当然,HTTPS和身份验证将以类似的方式处理。但是您必须提示输入用户名和密码,并根据请求更新HTTP标头。请参阅this link。
从我们的测试中,WinHTTP比WinINet快得多(当然因为它没有实现任何UI部分,并且没有链接到Internet Explorer库)。
您可以查看our Open Source classes来猜测WinINet和WinHTTP之间的API差异有多大(大多数代码在链接的单元中共享)。
答案 1 :(得分:0)
尝试修改SOAPHTTPTrans以静默处理错误。 在THTTPReqResp.HandleWinInetError中,最终会调用错误对话框:
Result := CallInternetErrorDlg
您可能检测到您的特定错误,您应该能够从HandleWinInetError返回0,或者至少不调用CallInternetErrorDlg。看看是否有帮助。