Получить сигнал sslerrors в QWebEngineView

Я разрабатываю приложение, в котором пользователю сначала нужно будет войти в систему. Я использую QWebEngineView для отображения страницы входа. Но на одной из машин страница не отображается. Я хочу знать, есть ли ошибки SSL. Как я могу получить сигнал sslerrors и подключить его к слоту. Пример кода ниже

from PyQt5.QtNetwork import QSslConfiguration, QSsl
from PyQt5.QtWidgets import QWidget, QGridLayout, QStatusBar, QApplication,\
    QMainWindow
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtCore import QCoreApplication, QMetaObject, QUrl

def set_ssl_protocol():
    default_config = QSslConfiguration.defaultConfiguration()
    default_config.setProtocol(QSsl.TlsV1_2)
    QSslConfiguration.setDefaultConfiguration(default_config)

set_ssl_protocol()

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        self.urlString = "https://www.yahoo.com"

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.webView = QWebEngineView(self.centralwidget)
        self.webView=QWebEngineView()
        self.webView.setUrl(QUrl("about:blank"))
#        self.webView.setUrl(QUrl("http://www.google.com/"))
        self.webView.setObjectName("webView")
        self.gridLayout.addWidget(self.webView, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.loadURL()
        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

    def loadURL(self):
        if not hasattr(self, 'page'):
            self.page = QWebEnginePage()
            self.webView.setPage(self.page)
        self.page.load(QUrl(self.urlString))


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Примечание. В Qt4 это было довольно просто, так как мы можем подключить сигнал page().networkAccessManager().sslerrors к слоту, тогда как в Qt5, поскольку запросы не выполняются через NetworkAccessManager, отлаживать немного сложно.


person TFA    schedule 18.10.2018    source источник


Ответы (1)


Если вы хотите получить информацию об ошибках, вызванных сертификатом SSL, путем перезаписи certificateError() метод QWebEnginePage, как показано ниже:

from PyQt5 import QtCore, QtWidgets, QtNetwork, QtWebEngineWidgets


def set_ssl_protocol():
    default_config = QtNetwork.QSslConfiguration.defaultConfiguration()
    default_config.setProtocol(QtNetwork.QSsl.TlsV1_2)
    QtNetwork.QSslConfiguration.setDefaultConfiguration(default_config)


class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
    def certificateError(self, certificateError):
        print(certificateError.errorDescription(), certificateError.url(), certificateError.isOverridable())
        error = certificateError.error()
        if error == QtWebEngineWidgets.WebEngineCertificateError.SslPinnedKeyNotInCertificateChain:
            print("SslPinnedKeyNotInCertificateChain")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateCommonNameInvalid:
            print("CertificateCommonNameInvalid")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateDateInvalid:
            print("CertificateDateInvalid")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateAuthorityInvalid:
            print("CertificateAuthorityInvalid")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateContainsErrors:
            print("CertificateContainsErrors")
        if error == QtWebEngineWidgets.WebEngineCertificateError.CertificateNoRevocationMechanism:
            print("CertificateNoRevocationMechanism")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateUnableToCheckRevocation:
            print("CertificateUnableToCheckRevocation")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateRevoked:
            print("CertificateRevoked")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateInvalid:
            print("CertificateAuthorityInvalid")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateWeakSignatureAlgorithm:
            print("CertificateWeakSignatureAlgorithm")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateNonUniqueName:
            print("CertificateNonUniqueName")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateWeakKey:
            print("CertificateWeakKey")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateNameConstraintViolation:
            print("CertificateNameConstraintViolation")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateValidityTooLong:
            print("CertificateValidityTooLong")
        elif error == QtWebEngineWidgets.WebEngineCertificateError.CertificateTransparencyRequired:
            print("CertificateTransparencyRequired")

        return super(WebEnginePage, self).certificateError(certificateError)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.webView = QtWebEngineWidgets.QWebEngineView()
        self.setCentralWidget(self.webView)
        page = WebEnginePage(self)
        self.webView.setPage(page)
        page.load(QtCore.QUrl("https://www.yahoo.com"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    set_ssl_protocol()
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Вы можете вернуть True или False, если вы хотите содержать запрос или нет, соответственно.

person eyllanesc    schedule 18.10.2018
comment
Спасибо за ответ. Поскольку страница пуста, я понятия не имею, в чем может быть ошибка. Может ли это быть связано только с ошибками сертификата? Если есть какие-то другие ошибки SSL, как мне узнать об этом? Я просто хотел узнать причину и отладить эту проблему. - person TFA; 18.10.2018
comment
@TFA Ваш вопрос заключается в том, как уведомить о наличии ошибок типа SSL, и метод, который я указываю, делает то, о чем вы просили, он охватывает все ошибки, поддерживаемые Qt. С другой стороны, если ошибка не связана с SSL, я не могу вам помочь, поскольку вы не предоставляете минимальный воспроизводимый пример. Наконец, если мой ответ поможет вам, не забудьте отметить его как правильный, если вы не знаете, как это сделать, просмотрите тур , это лучший способ поблагодарить - person eyllanesc; 18.10.2018
comment
@eyllansec Хотя этот минимальный пример достаточно хорош, чтобы понять проблему, проблема здесь в том, что ее нельзя воспроизвести на всех, кроме одной конкретной машины, что заставило меня теперь думать, что это, скорее всего, проблема, связанная с окружающей средой. Проголосовал за ваш ответ. - person TFA; 18.10.2018
comment
@TFA Что ж, если его нельзя воспроизвести, будет трудно помочь, поэтому вам предстоит выяснить, в чем его отличие от других машин. Все машины одной архитектуры? У них одинаковая ОС? Они одной версии? - person eyllanesc; 18.10.2018