2017-09-01 27 views
1

私の実装では、成功した認証の後、特定のURLに使用された資格情報をQNetworkAccessManagerがキャッシュしているようです。 異なるの資格情報を使用して同じURLへPyQt4のQNetworkAccessManagerで認証を強制する方法はありますか?

次の要求は成功しますが、それはキャッシュされた資格情報の代わりに、新しいものを(authenticationRequired信号が放出されていない)のみを使用しますので。

(Py)Qt4にキャッシュをクリアする方法や、キャッシュされたクレデンシャルを強制的に更新する方法はありますか?マネージャーを削除して新しいマネージャーを作成するだけですか?それとも、私が間違っていることがありますか?

Qt 5はclearAccessCache()メソッドを提供しますが、Qt 4では表示されていません。 、次の1が、それはすべきではないにもかかわらず、同様であるとすぐに1つの要求が正常に認証されるよう

import sys 
import json 
from PyQt4 import QtNetwork, QtGui, QtCore 

def show_reply_content(reply): 
    content = json.loads(str(reply.readAll())) 
    if 'authenticated' in content and content['authenticated']: 
     print 'authentication successful for user {}'.format(
      content['user']) 
     reply.manager().replies_authenticated += 1 

    # Quit when all replies are finished 
    reply.deleteLater() 
    reply.manager().replies_unfinished -= 1 
    if not reply.manager().replies_unfinished: 
     print 'number of successful authentications: {}'.format(
      reply.manager().replies_authenticated) 
     app.quit() 


def provide_credentials(reply, authenticator): 
    print 'Setting credentials for {}:\nusername: {}\n' \ 
      'password: {}\n\n'.format(reply.url(), 
            reply.credentials['username'], 
            reply.credentials['password']) 
    authenticator.setUser(reply.credentials['username']) 
    authenticator.setPassword(reply.credentials['password']) 

# Some initialization 
app = QtGui.QApplication(sys.argv) 
manager = QtNetwork.QNetworkAccessManager() 
manager.finished.connect(show_reply_content) 
manager.authenticationRequired.connect(provide_credentials) 
manager.replies_unfinished = 0 
manager.replies_authenticated = 0 

# Specify credentials 
all_credentials = [dict(username='aap', 
         password='njkrfnq'), 
        dict(username='noot', 
         password='asdfber')] 

# url authenticates successfully only for the specified credentials 
url = 'http://httpbin.org/basic-auth/{}/{}'.format(
    *all_credentials[1].values()) 

# Schedule requests 
replies = [] 
for credentials in all_credentials: 
    replies.append(
     manager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(url)))) 

    # Add credentials as dynamic attribute 
    replies[-1].credentials = credentials 

    manager.replies_unfinished += 1 

# Start event loop 
app.exec_() 

この小さな例では、問題を示しています。

+0

Qt4の特定のバージョンは使用していますか?このバグは、[QTBUG-15566](https://bugreports.qt.io/browse/QTBUG-15566)と非常によく似ています。 – ekhumoro

+0

関連情報:[QNetworkAccessManager - 認証を実施する方法](http://thread.gmane.org/gmane.comp.lib.qt.user/3141) – ekhumoro

+0

Qtバージョンについてはわかりませんが、私はPyQt4を使用しています.11.4。私はまだそのバグ報告を調べなければなりませんが、2番目のリンクは私に有望な 'QNetworkRequest.AuthenticationReuseAttribute'を指摘しました。残念ながら、 'request.setAttribute(QNetworkRequest.AuthenticationReuseAttribute、QNetworkRequest.Manual)'を使った最初の試みはうまくいきませんでした。すべてのリクエストは401で拒否されました。これについては後で説明します。 – Dennis

答えて

1

それはまだ開いているいくつかの類似したQtのバグレポートがある結局のところ:QTBUG-16835QTBUG-30433 ...

私はQNetworkRequest.AuthenticationReuseAttributeを使用することが可能であるべきと思いますが、私は複数の要求とその作品を作ることができませんでした異なる(有効な)資格情報を持つ同じURLに変更します。

authenticationRequiredシグナル/スロットについてすべて忘れて、正確にas described hereの各要求に生のヘッダー(RFC 7617)を追加することが考えられます。 @ekhumoroがで指摘したように、しかし

request = QtNetwork.QNetworkRequest(QtCore.QUrl(url)) 
header_data = QtCore.QByteArray('{}:{}'.format(
    credentials['username'], credentials['password'])).toBase64() 
request.setRawHeader('Authorization', 'Basic {}'.format(header_data)) 
replies.append(manager.get(request)) 

authenticationRequired信号/スロット結合を除去し、(PyQt4とのPython 2.7の場合)、次の行によってmanager.get()一部を置換を意味する例で

上のコメント:これはどれくらい安全かわかりません。

関連する問題