1

I'm developing an application where the user will have to log-in first. I'm using QWebEngineView to show the login page. But in one of the machines the page doesn't show up. I want to know if there are any SSL errors. How can I get the sslerrors signal and connect it to a slot. Sample code below

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_())

Note: In Qt4 it was quite easy as we can connect page().networkAccessManager().sslerrors signal to the slot whereas in Qt5 since requests are not made through NetworkAccessManager it's a bit difficult to debug.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
TFA
  • 81
  • 10

1 Answers1

1

If you want to obtain information about the errors caused by the SSL certificate by overwriting the certificateError() method of QWebEnginePage as shown below:

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_())

You can return True or False if you want to contain the request or not, respectively.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thanks for responding. Since the page is blank I've no clue about what might be the error. Can it be only be attributed to Certificate Errors alone? If there are some other SSL Errors how do I get to know? I just wanted to know the reason and debug this issue. – TFA Oct 18 '18 at 06:48
  • @TFA Your question is how to notify if there are SSL type errors and the method that I indicate does what you asked for, this covers all the errors supported by Qt. On the other hand if the error is not by SSL I could not help you since you do not provide a [mcve]. Finally, if my answer helps you, do not forget to mark it as correct, if you do not know how to do it, review the [tour], that is the best way to thank – eyllanesc Oct 18 '18 at 06:56
  • @eyllansec Though this minimal example is good enough to apprehend the issue, the problem here is, it can't be reproduced in all but one specific machine which made me think now that it's most likely to be environment specific issue. Upvoted your answer. – TFA Oct 18 '18 at 07:11
  • @TFA Well, if it can not be reproduced it will be difficult to help so it will be up to you to discover what difference it has with other machines. Are all the machines of the same architecture? Do they have the same OS? Are they the same version? – eyllanesc Oct 18 '18 at 07:14