在我的跨平台应用程序中,我使用QNetworkAccessManager将HTTP请求发送到需要身份验证的HTTP服务。我最近升级到了QT5,在MacOSX上让我感到完全惊讶的是,在某些情况下,我的应用程序将尽快向我的服务发送大量请求。

经过一些调试后,事实证明只有当我在请求中指定错误的身份验证凭据时,才会发生这种情况。如果在我的HTTP请求中指定了无效的用户名/密码,QNetworkAccessManager将无限期地向我的服务发送请求。

我的代码在以前的QT版本中已经使用了很长时间,因此我决定必须在QT5中使用它。

最佳答案

我偶然发现了QT5中添加的以下增强功能:https://bugreports.qt.io/browse/QTBUG-22033

基本上,此增强功能背后的想法是,如果中间代理需要身份验证凭据,则检查钥匙串中的用户名/密码。事实证明,这是错误实现的,并且此代码已添加到QNetworkAccessManager :: authenticationRequired()信号中,而不是添加到proxyAuthenticationRequired()信号中。

关于此问题的有趣部分是,我没有为我的应用程序设置代理,也没有为我使用的QNetworkAccessManager设置代理。这使得这个问题很难调试!

由于位置不正确,任何“ authenticationRequired”信号都会发生这种“钥匙串查询”。底层的getProxyAuth()方法正在调用具有空白主机名的“ SecKeychainFindInternetPassword”,该主机名与我的钥匙串中的第一个“ Internet密码”匹配,并使用它使用此新凭据将请求发送到我的服务。想象一下,当我看到其他/个人密码之一发送到我的HTTP服务时,我感到惊讶!

这不仅是安全问题,而且还会在您的应用中引起无限循环。我在QT上打开了一个与此有关的错误:https://bugreports.qt.io/browse/QTBUG-30434

有临时解决方案吗?有!我寻找了暂时解决此问题的方法。这是一个讨厌的黑客。但这一直有效,直到QT家伙连续获得成功为止。该hack之所以有效,是因为它确保“ SecKeychainFindInternetPassword”与钥匙串中的任何条目都不匹配,因此跳过了“钥匙串查询”。

基本上,我将代理主机名设置为“”而不是“”,这将防止任何匹配导致我的应用程序中发生infite循环。

解决方法:

 QNetworkProxy proxy = manager_->proxy();
 proxy.setHostName(" ");
 manager_->setProxy(proxy);


我希望在下一版的QT中能够解决此问题,因此我可以删除此可怕的骇客。

关于macos - 在MacOSX上,当指定无效的身份验证凭据时,QNetworkAccessManager进入无限循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15707124/

10-09 06:39