Search code examples
c++qtoauth-2.0qt5pkce

Does QtNetworkAuth support PKCE


I use Qt5. I did not find any documentation on how to enable PKCE when using QOAuth2AuthorizationCodeFlow.

If so, please provide the link. If there is no support, how can this feature be added to it?

I added code_challenge and code_challenge_method, but it is not enough. I don't know what the next step is.

#include <QtNetworkAuth/QtNetworkAuth>

void loginHelper()
{
   auto* authFlow = new QOAuth2AuthorizationCodeFlow;
   QObject::connect(authFlow, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);
   authFlow->setScope("openid profile email mobile");
   authFlow->setAuthorizationUrl(QUrl("https://accounts.XYZ.com/core/connect/authorize")); // url is changed
   authFlow->setClientIdentifier("desktop.test");
   authFlow->setAccessTokenUrl(QUrl("https://accounts.XYZ.com/core/connect/token")); // url is changed
   authFlow->setClientIdentifierSharedKey("0323af0d-efe2-fcec-b450-72f102530a77");
   authFlow->setModifyParametersFunction([=](QAbstractOAuth::Stage, QVariantMap* params)
      {
         params->insert("code_challenge", "1Kht0Wkyt_WvDngoM_AIOYPPOWG8lzVG1g1zk28TjSo");
         params->insert("code_challenge_method", "S256");
      });
   auto* replyHandler = new QOAuthHttpServerReplyHandler(1234); // port number
   authFlow->setReplyHandler(replyHandler);
   QObject::connect(authFlow, &QOAuth2AuthorizationCodeFlow::granted, []()
      {
         qDebug() << "Access Granted!";
      });
   authFlow->grant();
}

Solution

  • The next step is to set code_verifier at RequestingAccessToken stage.

    auto code_verifier = (QUuid::createUuid().toString(QUuid::WithoutBraces) +
       QUuid::createUuid().toString(QUuid::WithoutBraces)).toLatin1(); // 43 <= length <= 128
    auto code_challenge = QCryptographicHash::hash(code_verifier, QCryptographicHash::Sha256).toBase64(
       QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
    authFlow.setModifyParametersFunction([=](QAbstractOAuth::Stage stage, QVariantMap* params)
    {
       switch (stage)
       {
       case QAbstractOAuth::Stage::RequestingAuthorization:
          params->insert("code_challenge", code_challenge);
          params->insert("code_challenge_method", "S256");
          break;
       case QAbstractOAuth::Stage::RequestingAccessToken:
          params->insert("code_verifier", code_verifier);
          break;
       }
    });