Solved QNetwokrAccessManager: QNetworkReply::SslHandshakeFailedError
-
I want to read json data from a host with a predefined API with this code:
#include "myarca.h" #include "ui_myarca.h" MyArca::MyArca(QWidget *parent) : QWidget(parent) , ui(new Ui::MyArca) { ui->setupUi(this); connect(ui->pushButtonGet, &QPushButton::clicked, this, &MyArca::on_clicked_PushButtonGet); connect(ui->pushButtonPost, &QPushButton::clicked, this, &MyArca::on_clicked_PushButtonPost); } MyArca::~MyArca() { delete ui; } void MyArca::on_clicked_PushButtonGet() { qDebug() << "Get"; qDebug() << "openSSL Version:" << QSslSocket::sslLibraryBuildVersionString(); QSslConfiguration sslConfiguration(QSslConfiguration::defaultConfiguration()); sslConfiguration.setProtocol(QSsl::TlsV1_0); QUrl url; QUrl url = QUrl::.fromUserInput("https://192.20.2.101:11863/test-request/api/v1/users"); QNetworkRequest request(url); request.setUrl(url); request.setRawHeader("Accept-Encoding", "gzip, deflate"); request.setRawHeader("Content-Type", "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json")); request.setSslConfiguration(sslConfiguration); reply = manager.get(request); connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError code) { qDebug() << "Error" << code << reply->errorString(); } ); connect(reply, &QNetworkReply::downloadProgress, this, &MyArca::on_downloadProgress); connect(reply, &QNetworkReply::readyRead, this, &MyArca::on_downloadReadyRead); connect(reply, &QNetworkReply::finished, this, &MyArca::on_downloadFinished); } void MyArca::on_clicked_PushButtonPost() { qDebug() << "Post"; } void MyArca::on_downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { qDebug() << "bytes received" << bytesReceived; qDebug() << "bytes total " << bytesTotal; } void MyArca::on_downloadReadyRead() { qDebug() << "ready read"; qDebug() << reply->readAll(); } void MyArca::on_downloadFinished() { qDebug() << "finished"; }
I get the following outputs:
openSSL Version: "OpenSSL 1.1.1c 28 May 2019" Error QNetworkReply::SslHandshakeFailedError "Im Ablauf des SSL-Protokolls ist ein Fehler aufgetreten. bytes received 0 bytes total 0 finished
How can I set the right protocol and which one do I have to chose from this list https://doc.qt.io/qt-5/qssl.html#SslProtocol-enum
With this curl command I get the correct answer:
curl -G -k -H 'Accept: application/json' https://192.20.2.101:11863/test-request/api/v1/users
Or what am I doing wrong?
Thanks for your help.
-
Hi,
You are missing the https in your url.
What OS are you running ?
What version of OpenSSL did you install ? -
I'm running linux.
OpenSSL 1.1.1c 28 May 2019 -
I found the solution now. I also had to add the certificate. my code looks like this now:
void MyArca::on_clicked_PushButtonGet() { qDebug() << "Get"; qDebug() << "openSSL Version:" << QSslSocket::sslLibraryBuildVersionString(); QSslConfiguration sslConfiguration(QSslConfiguration::defaultConfiguration()); const auto certs = QSslCertificate::fromPath("/tmp/arca.pem", QSsl::Pem, QRegExp::Wildcard); for (const QSslCertificate &cert : certs) { qDebug() << cert.issuerInfo(QSslCertificate::Organization); } sslConfiguration.setCaCertificates(certs); sslConfiguration.setProtocol(QSsl::AnyProtocol); QUrl url = QUrl::fromUserInput("https://192.20.2.101:11863/test-request/api/v1/users"); qDebug() << "url" << url.toString(); QNetworkRequest request(url); request.setSslConfiguration(sslConfiguration); request.setUrl(url); request.setRawHeader("Authorization", "Bearer <some token issued by a keycloak server>"); request.setRawHeader("Accept-Encoding", "gzip, deflate"); request.setRawHeader("Content-Type", "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json")); request.setSslConfiguration(sslConfiguration); reply = manager.get(request); connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError code) { qDebug() << "Error" << code << reply->errorString(); } ); connect(reply, &QNetworkReply::downloadProgress, this, &MyArca::on_downloadProgress); connect(reply, &QNetworkReply::readyRead, this, &MyArca::on_downloadReadyRead); connect(reply, &QNetworkReply::finished, this, &MyArca::on_downloadFinished); connect(&manager, &QNetworkAccessManager::sslErrors, this, &MyArca::on_sslErrors); connect(&manager, &QNetworkAccessManager::authenticationRequired, this, &MyArca::on_authenticationRequired); }
The server requires the Authorization Header to be set to a token.
request.setRawHeader("Authorization", "Bearer <some keycloack token>");
The token is issued by a keycloak server where the user has to login. After a successful login the keycloak server issues a token, which has to be set in the Authorization Header. With the setup I have now, I have to manually copy the token into request.setRawHeader("Authorization", "Bearer ..."); which is obviously not very convenient. Is there a way to obtain the token directly from the keycloak server? I searched around for many hours, but I couldn't find a solution. It would be great if somebody could point me in the right direction.
-
One thing you can do is check if you have that token, if not, do the request you need to retrieve it and then continue.
-
Thanks for your help. It is working now.