Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. OAuth2 QOAuthHttpServerReplyHandler HTTPS/SSL support?
Forum Updated to NodeBB v4.3 + New Features

OAuth2 QOAuthHttpServerReplyHandler HTTPS/SSL support?

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 5 Posters 3.3k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Alex94102A Offline
    Alex94102A Offline
    Alex94102
    wrote on last edited by
    #1

    Hi,

    I am integrating with a provider that does NOT accept regular HTTP URIs for Callback URLs. It requires everything to be HTTPS.

    So the OAuth2 code looks like this:

    auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
    replyHandler->setCallbackPath(QString("/"));
    oauth2.setReplyHandler(replyHandler);
    

    But this creates a TCP/IP server port that is HTTP and not HTTPS and things just fall apart. Is there a way to make it work with HTTPS?

    Thank you!

    JonBJ 1 Reply Last reply
    0
    • Alex94102A Alex94102

      Hi,

      I am integrating with a provider that does NOT accept regular HTTP URIs for Callback URLs. It requires everything to be HTTPS.

      So the OAuth2 code looks like this:

      auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
      replyHandler->setCallbackPath(QString("/"));
      oauth2.setReplyHandler(replyHandler);
      

      But this creates a TCP/IP server port that is HTTP and not HTTPS and things just fall apart. Is there a way to make it work with HTTPS?

      Thank you!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @Alex94102
      Here you go: https://bugreports.qt.io/browse/QTBUG-64615

      testmonkeyT 1 Reply Last reply
      2
      • Alex94102A Offline
        Alex94102A Offline
        Alex94102
        wrote on last edited by
        #3

        Ahh, thank you. I looked at the bug and tried to register the app just with localhost:1337 but the site didn't like it. It want the http(s) in front of it, and then replaces that with https anyway.

        Assuming that I open the browser in WebEngineView, can I intercept the redirect and change https with http? If so, do you have any pointers for that?

        thank you,
        alex

        1 Reply Last reply
        0
        • Alex94102A Offline
          Alex94102A Offline
          Alex94102
          wrote on last edited by
          #4

          Ok, I found a working solution for this, but it's really another "hack" :-)
          I hope there would be a better way to get this OAuth2 to work the way it should. Also, on a different note, I emailed the provider about this issue and they said they are going to change it for localhost and leave it HTTP if it was defined HTTP.

          I was able to use concepts from this page, by leveraging the RequestInterceptor:

          https://forum.qt.io/topic/69135/how-to-send-network-requests-in-qwebengine/2

          then in my code, I did something like this to alter the URL (i did a redirect):

          void WebUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) {
          QString rsrct = "";
          switch(info.resourceType()){
          case 0:rsrct="ResourceTypeMainFrame = 0, // top level page";break;
          // case 1:rsrct="ResourceTypeSubFrame, // frame or iframe";break;
          // case 2:rsrct="ResourceTypeStylesheet, // a CSS stylesheet";break;
          // case 3:rsrct="ResourceTypeScript, // an external script";break;
          // case 4:rsrct="ResourceTypeImage, // an image (jpg/gif/png/etc)";break;
          // case 5:rsrct="ResourceTypeFontResource, // a font";break;
          // case 6:rsrct="ResourceTypeSubResource, // an other subresource.";break;
          // case 7:rsrct="ResourceTypeObject, // an object (or embed) tag for a plugin,";break;
          // case 8:rsrct="ResourceTypeMedia, // a media resource.";break;
          // case 9:rsrct="ResourceTypeWorker, // the main resource of a dedicated worker.";break;
          // case 10:rsrct="ResourceTypeSharedWorker, // the main resource of a shared worker.";break;
          // case 11:rsrct="ResourceTypePrefetch, // an explicitly requested prefetch";break;
          // case 12:rsrct="ResourceTypeFavicon, // a favicon";break;
          // case 13:rsrct="ResourceTypeXhr, // a XMLHttpRequest";break;
          // case 14:rsrct="ResourceTypePing, // a ping request for <a ping>";break;
          // case 15:rsrct="ResourceTypeServiceWorker, // the main resource of a service worker.";break;
          // case 16:rsrct="ResourceTypeUnknown";break;

          default : rsrct="Else";return;
          }
          

          qDebug()<<"\t"<<Q_FUNC_INFO<<":\n\t\t" << "WebUrlRequestInterceptor::interceptRequest " <<info.requestMethod()
          <<"\r\n "<<info.requestUrl()<<" "<<rsrct <<"\r\n";
          if (info.requestUrl().toString() == "https://localhost/") {
          qDebug()<<"*** REDIRECTING";
          const QUrl u("http://localhost/");
          info.redirect(u);
          }

          Alex94102A 1 Reply Last reply
          0
          • Alex94102A Alex94102

            Ok, I found a working solution for this, but it's really another "hack" :-)
            I hope there would be a better way to get this OAuth2 to work the way it should. Also, on a different note, I emailed the provider about this issue and they said they are going to change it for localhost and leave it HTTP if it was defined HTTP.

            I was able to use concepts from this page, by leveraging the RequestInterceptor:

            https://forum.qt.io/topic/69135/how-to-send-network-requests-in-qwebengine/2

            then in my code, I did something like this to alter the URL (i did a redirect):

            void WebUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) {
            QString rsrct = "";
            switch(info.resourceType()){
            case 0:rsrct="ResourceTypeMainFrame = 0, // top level page";break;
            // case 1:rsrct="ResourceTypeSubFrame, // frame or iframe";break;
            // case 2:rsrct="ResourceTypeStylesheet, // a CSS stylesheet";break;
            // case 3:rsrct="ResourceTypeScript, // an external script";break;
            // case 4:rsrct="ResourceTypeImage, // an image (jpg/gif/png/etc)";break;
            // case 5:rsrct="ResourceTypeFontResource, // a font";break;
            // case 6:rsrct="ResourceTypeSubResource, // an other subresource.";break;
            // case 7:rsrct="ResourceTypeObject, // an object (or embed) tag for a plugin,";break;
            // case 8:rsrct="ResourceTypeMedia, // a media resource.";break;
            // case 9:rsrct="ResourceTypeWorker, // the main resource of a dedicated worker.";break;
            // case 10:rsrct="ResourceTypeSharedWorker, // the main resource of a shared worker.";break;
            // case 11:rsrct="ResourceTypePrefetch, // an explicitly requested prefetch";break;
            // case 12:rsrct="ResourceTypeFavicon, // a favicon";break;
            // case 13:rsrct="ResourceTypeXhr, // a XMLHttpRequest";break;
            // case 14:rsrct="ResourceTypePing, // a ping request for <a ping>";break;
            // case 15:rsrct="ResourceTypeServiceWorker, // the main resource of a service worker.";break;
            // case 16:rsrct="ResourceTypeUnknown";break;

            default : rsrct="Else";return;
            }
            

            qDebug()<<"\t"<<Q_FUNC_INFO<<":\n\t\t" << "WebUrlRequestInterceptor::interceptRequest " <<info.requestMethod()
            <<"\r\n "<<info.requestUrl()<<" "<<rsrct <<"\r\n";
            if (info.requestUrl().toString() == "https://localhost/") {
            qDebug()<<"*** REDIRECTING";
            const QUrl u("http://localhost/");
            info.redirect(u);
            }

            Alex94102A Offline
            Alex94102A Offline
            Alex94102
            wrote on last edited by
            #5

            @Alex94102 I suspect the OAuth2 library is broken. It doesn't URL Encode the POST request body, I verified that. The technique used doesn't work properly.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              Would it be possible for you to provide a minimal compilable example that reproduces that behaviour ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • Alex94102A Offline
                Alex94102A Offline
                Alex94102
                wrote on last edited by
                #7

                Hi,

                so essentially I went down that path and the service call for retrieving the refresh_token was failing and I couldn't figure out why. To diagnose that I tested that with an echo server to print what was being sent and compare that with a working CURL call. What I noticed is that the parameters that were placed in the body were not URL encoded but they were left as is. Then I looked at the source code (see below) and this is the method where he's doing the POST (the body of the request is created by this line const QString data = query.toString(QUrl::FullyEncoded);

                By replicating this functionality and properly encoding the parameter values only with QUrl::toPercentEncoding() everything works as it should. Let me know if you need more details...:

                void QOAuth2AuthorizationCodeFlow::requestAccessToken(const QString &code)
                {
                Q_D(QOAuth2AuthorizationCodeFlow);
                using Key = QAbstractOAuth2Private::OAuth2KeyString;

                QVariantMap parameters;
                QNetworkRequest request(d->accessTokenUrl);
                QUrlQuery query;
                parameters.insert(Key::grantType, QStringLiteral("authorization_code"));
                parameters.insert(Key::code, QUrl::toPercentEncoding(code));
                parameters.insert(Key::redirectUri, QUrl::toPercentEncoding(callback()));
                parameters.insert(Key::clientIdentifier, QUrl::toPercentEncoding(d->clientIdentifier));
                if (!d->clientIdentifierSharedKey.isEmpty())
                    parameters.insert(Key::clientSharedSecret, d->clientIdentifierSharedKey);
                if (d->modifyParametersFunction)
                    d->modifyParametersFunction(Stage::RequestingAccessToken, &parameters);
                query = QAbstractOAuthPrivate::createQuery(parameters);
                request.setHeader(QNetworkRequest::ContentTypeHeader,
                                  QStringLiteral("application/x-www-form-urlencoded"));
                
                const QString data = query.toString(QUrl::FullyEncoded);
                QNetworkReply *reply = d->networkAccessManager()->post(request, data.toUtf8());
                d->currentReply = reply;
                QAbstractOAuthReplyHandler *handler = replyHandler();
                QObject::connect(reply, &QNetworkReply::finished,
                                 [handler, reply] { handler->networkReplyFinished(reply); });
                QObjectPrivate::connect(d->replyHandler.data(), &QAbstractOAuthReplyHandler::tokensReceived, d,
                                        &QOAuth2AuthorizationCodeFlowPrivate::_q_accessTokenRequestFinished,
                                        Qt::UniqueConnection);
                QObjectPrivate::connect(d->networkAccessManager(),
                                        &QNetworkAccessManager::authenticationRequired,
                                        d, &QOAuth2AuthorizationCodeFlowPrivate::_q_authenticate,
                                        Qt::UniqueConnection);
                

                }

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  It looks like you found a bug :)

                  Did you already check the bug report system to see if there was something related ?

                  If not, please consider opening a new report providing all the information you have here (do not just link this thread, it's better to have all there).

                  Since you also find a solution, would you consider submitting a patch directly ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  2
                  • Alex94102A Offline
                    Alex94102A Offline
                    Alex94102
                    wrote on last edited by
                    #9

                    Hi,

                    to be honest, I don't know how to submit a patch, I've never done it before. Would that be a patch file? I am a little lost. But essentially the code above where the "data" variable is populated by that statement needs to be replaced by something like this (just to get the idea). In my case, I used a QVariantMap for storing my parameter values, and then I build the QByteArray for the request using the method below. :

                    QByteArray MyOwnOAuth2::buildBodyPayload()
                    {
                    bool first=true;
                    QByteArray body;
                    for(QVariantMap::const_iterator iter = mBodyParameters.begin(); iter != mBodyParameters.end(); ++iter) {
                    qDebug() << iter.key() << iter.value();
                    if (!first) {
                    body.append(QString("&").toUtf8());
                    }
                    QString name = iter.key();
                    QString value = QUrl::toPercentEncoding(iter.value().toString());
                    body.append(name.toUtf8());
                    body.append(QString("=").toUtf8());
                    body.append(value.toUtf8());
                    first = false;
                    }
                    return body;
                    }

                    aha_1980A 1 Reply Last reply
                    0
                    • Alex94102A Alex94102

                      Hi,

                      to be honest, I don't know how to submit a patch, I've never done it before. Would that be a patch file? I am a little lost. But essentially the code above where the "data" variable is populated by that statement needs to be replaced by something like this (just to get the idea). In my case, I used a QVariantMap for storing my parameter values, and then I build the QByteArray for the request using the method below. :

                      QByteArray MyOwnOAuth2::buildBodyPayload()
                      {
                      bool first=true;
                      QByteArray body;
                      for(QVariantMap::const_iterator iter = mBodyParameters.begin(); iter != mBodyParameters.end(); ++iter) {
                      qDebug() << iter.key() << iter.value();
                      if (!first) {
                      body.append(QString("&").toUtf8());
                      }
                      QString name = iter.key();
                      QString value = QUrl::toPercentEncoding(iter.value().toString());
                      body.append(name.toUtf8());
                      body.append(QString("=").toUtf8());
                      body.append(value.toUtf8());
                      first = false;
                      }
                      return body;
                      }

                      aha_1980A Offline
                      aha_1980A Offline
                      aha_1980
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @Alex94102 said in OAuth2 QOAuthHttpServerReplyHandler HTTPS/SSL support?:

                      to be honest, I don't know how to submit a patch, I've never done it before. Would that be a patch file?

                      A patch is the difference in code between the original and your new version: https://en.wikipedia.org/wiki/Patch_(computing)

                      The preferred way to get patches into Qt is through Gerrit, however small patches may also be attached to the bug report. In any case, we can help you with that, preferred in a separate discussion.

                      body.append(QString("&").toUtf8());

                      That (and the similar line) should be simplified to: body.append("&");

                      PS: Please add a link to the bug report here, so we can follow. Thanks!

                      Qt has to stay free or it will die.

                      1 Reply Last reply
                      2
                      • Alex94102A Offline
                        Alex94102A Offline
                        Alex94102
                        wrote on last edited by
                        #11

                        Sorry, I was out of town. I think I am familiar with the patch utility, my question is more around the whole process. Maybe someone can get back to me directly so that we are not polluting this topic with these kind of general questions. At the present time the code that I put together is not using this library anymore as it was defective, so for me to properly test I would have to make some changes to my code and to make it use this patched library instead.

                        What I am looking for is some pointers (not c++) on how to get this done (example):

                        1. File a JIRA bug report
                        2. Prepare the patch if bug confirmed
                        3. This is where I am struggling, would I send the simple patch file to the maintainer? I guess so, submit that in JIRA?
                        4. Would I need also submit unit tests for this?
                        5. Anythig else?

                        Thanks a lot,
                        alex

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12
                          1. Yes if not already existing
                          2. Since you are experiencing this and have a solution, say it in the report.
                          3. The nicest and fastest would be to submit the patch yourself for review. See the gerrit introcution.
                          4. Since you are solving a specific problem, it would be best since it's not already covered by a test
                          5. Be patient, sometime patches can get reviewed quickly while some needs more time. It has nothing to do with the fact that its your first submission.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          Alex94102A 1 Reply Last reply
                          1
                          • SGaistS SGaist
                            1. Yes if not already existing
                            2. Since you are experiencing this and have a solution, say it in the report.
                            3. The nicest and fastest would be to submit the patch yourself for review. See the gerrit introcution.
                            4. Since you are solving a specific problem, it would be best since it's not already covered by a test
                            5. Be patient, sometime patches can get reviewed quickly while some needs more time. It has nothing to do with the fact that its your first submission.
                            Alex94102A Offline
                            Alex94102A Offline
                            Alex94102
                            wrote on last edited by
                            #13

                            @SGaist Ok, I have enough info to get started. Thank you.

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              You're welcome !

                              One last thing: if you open a new report, please post a link to it here so people can more easily find it :)

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              0
                              • JonBJ JonB

                                @Alex94102
                                Here you go: https://bugreports.qt.io/browse/QTBUG-64615

                                testmonkeyT Offline
                                testmonkeyT Offline
                                testmonkey
                                wrote on last edited by
                                #15

                                bump, bit of a necropost, but still an issue.

                                @JonB said in OAuth2 QOAuthHttpServerReplyHandler HTTPS/SSL support?:

                                @Alex94102
                                Here you go: https://bugreports.qt.io/browse/QTBUG-64615

                                any luck with getting QSslSocket bits into qoauthhttpserverreplyhandler ?? I am trying to interact with a service that has just started enforcing https for callbacks.

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved