В MacOSX QNetworkAccessManager попадает в бесконечный цикл, когда указаны неверные учетные данные
В моем кроссплатформенном приложении я использую QNetworkAccessManager для отправки HTTP-запросов к моей HTTP-службе, которая требует аутентификации. Я недавно обновился до QT5, и, к моему удивлению, в MacOSX мое приложение отправило огромное количество запросов в мой сервис как можно быстрее в некоторых сценариях.
После некоторой отладки выясняется, что это произойдет только в том случае, если в моих запросах будут указаны неверные учетные данные. QNetworkAccessManager будет бесконечно отправлять запросы в мой сервис, если в моих HTTP-запросах будут указаны неверные имя пользователя и пароль.
Мой код долгое время работал в предыдущих версиях QT, поэтому я решил, что это должно быть что-то с QT5.
1 ответ
Я наткнулся на следующее улучшение, которое было добавлено в QT5: https://bugreports.qt.io/browse/QTBUG-22033
По сути, идея этого усовершенствования заключается в проверке цепочки для ключей для имени пользователя / пароля, если промежуточный прокси-сервер требует учетных данных аутентификации. Оказывается, это было плохо реализовано, и этот код был добавлен к сигналу QNetworkAccessManager::authenticationRequired(), а не добавлен к сигналу proxyAuthenticationRequired().
Интересная часть этой проблемы заключается в том, что я не установил ни прокси для своего приложения, ни QNetworkAccessManager, который я использую. Что делает эту проблему такой сложной для отладки!
Из-за неправильного размещения этот "запрос цепочки для ключей" происходит с любым сигналом authenticationRequired. Базовый метод getProxyAuth() вызывает "SecKeychainFindInternetPassword" с пустым именем хоста, которое соответствует первому "интернет-паролю" из моей цепочки для ключей, и использует его для отправки запроса в мой сервис с этими новыми учетными данными. Вообразите мое удивление, когда я увидел, что один из моих / личных паролей был отправлен в мою службу HTTP!
Это не только проблемы безопасности, но и бесконечный цикл в вашем приложении. Я открыл ошибку с QT по этому поводу: https://bugreports.qt.io/browse/QTBUG-30434
Есть ли временное решение? Есть! Я искал решение этой проблемы какое-то время. Это неприятный хак. Но это работает до тех пор, пока парни из QT не получат своих уток подряд. Этот хак работает, потому что он гарантирует, что "SecKeychainFindInternetPassword" не соответствует ни одной записи в цепочке для ключей, и, следовательно, пропускает этот "запрос цепочки для ключей".
По сути, я устанавливаю прокси-имя хоста на " " вместо " ", что предотвратит любое совпадение, которое вызывает бесконечный цикл в моем приложении.
Временное решение:
QNetworkProxy proxy = manager_->proxy();
proxy.setHostName(" ");
manager_->setProxy(proxy);
Я надеюсь, что это будет решено в следующей версии QT, поэтому я могу удалить этот ужасный хак.