Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
5.4.0, 5.12.3
-
Windows 7, Windows 10
-
ed4f85d5f3 (qt/tqtc-qtbase/6.2)
Description
Test steps:
1. Create a QNetworkAccessManager instance
2. Connect its authenticationRequired() signal to a slot
3. Call pMgr->get(QNetworkRequest(QUrl("https://a.com/ews/Exchange.asmx"))), where the supplied URL is to a server that uses NTLM authentication.
Issue:
If using Qt 4.7.3, the QNetworkAccessManager::authenticationRequired() signal is emitted to request the authentication credentials, as expected.
However, using the same code but with Qt 5.4.0, the QNetworkAccessManager::authenticationRequired() signal is not emitted.
Test code:
class NetworkTest : public QObject { Q_OBJECT public: NetworkTest() : QObject(NULL) { m_pManager = new QNetworkAccessManager(this); connect(m_pManager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(onSslErrors(QNetworkReply*, const QList<QSslError>&))); connect(m_pManager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); QTimer::singleShot(100, this, SLOT(testRequest())); } public slots: void testRequest() { qDebug("!!! testRequest\n"); m_pManager->get(QNetworkRequest(QUrl("https://something.com/ews/Exchange.asmx"))); } void authenticationRequired(QNetworkReply * reply, QAuthenticator * authenticator) { qDebug("!!! authenticationRequired\n"); } void onSslErrors(QNetworkReply * reply, const QList<QSslError> & errors) { qDebug("!!! onSslErrors\n"); reply->ignoreSslErrors(); } private: QNetworkAccessManager *m_pManager; };
Clues:
I see that QHttpNetworkConnectionPrivate::handleAuthenticateChallenge() is being called, but the first time it is called, it executes the following block of code:
} else if (priv->phase == QAuthenticatorPrivate::Start) { // If the url's authenticator has a 'user' set we will end up here (phase is only set to 'Done' by // parseHttpResponse above if 'user' is empty). So if credentials were supplied with the request, // such as in the case of an XMLHttpRequest, this is our only opportunity to cache them. emit reply->cacheCredentials(reply->request(), auth); }
Based on the comment, I think that this might be incorrect, because at that point when using NTLM authentication, the url's authenticator does not have 'user' set. As a consequence of calling this code, an entry is added to the authentication cache with a blank username, blank password, and a domain of "/".
Later, when QNetworkAccessManagerPrivate::authenticationRequired() is executed, it seemingly incorrectly bails out with the following block of code because the cached authentication is not null (since its domain is "/") but it also isn't correct:
QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedCredentials(url, authenticator); if (!cred.isNull()) { ... return; }
Attachments
Issue Links
- duplicates
-
QTBUG-60901 NTLM authentication fails and goes into a loop trying to authenticate
- Closed
For Gerrit Dashboard: QTBUG-44096 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
188509,2 | Network: Emit authenticationRequired when using Ntlm | 5.8 | qt/qtbase | Status: ABANDONED | +1 | 0 |
265900,4 | Network: Emit authenticationRequired when using Ntlm | dev | qt/qtbase | Status: MERGED | +2 | 0 |
393469,2 | Network: Emit authenticationRequired when using Ntlm | 6.3 | qt/qtbase | Status: MERGED | +2 | 0 |
393470,2 | Network: Emit authenticationRequired when using Ntlm | 6.2 | qt/qtbase | Status: MERGED | +2 | 0 |
393473,2 | Network: Emit authenticationRequired when using Ntlm | tqtc/lts-5.15 | qt/tqtc-qtbase | Status: MERGED | +2 | 0 |