Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Access token for authorization code flow



  • I am using Authorization code flow QOauth2.0 for login. I am facing some issues and don't have clarity -

    1. Can we pass user name and password like how we do for ROPC flow? Oauth 2.0 APIs support it? or it is logical to do like this?

    2. I am opening desktop services and receiving authorization code, but unable to receive access token. I am unsure what am I doing wrong. authorizationCallbackReceived signal is getting called twice but granted is not getting called even once. (commented part i think is workaround to use networkaccessmanager and make a call, though it works) . Below is code snippet, I am looking for the way how Qt API can directly provide me access token without networkaccessmanager use -

              AuthorizationCodeFlow::AuthorizationCodeFlow(QObject *parent) : QObject(parent)
              {
                  m_authorizationCodeFlowPtr = new QOAuth2AuthorizationCodeFlow(this);
                  connect(m_authorizationCodeFlowPtr, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);
                  connect(m_authorizationCodeFlowPtr, &QOAuth2AuthorizationCodeFlow::granted, [=]()
                  {
                      qDebug() << "access granted";
                  });
                  connect(m_authorizationCodeFlowPtr, &QOAuth2AuthorizationCodeFlow::authorizationCallbackReceived, [=](const QVariantMap data)
                  {
                      if (false == data.isEmpty())
                      {
                          m_code = data.value("code").toString();
                          if(!m_code.isEmpty())
                          {
                              //                QJsonObject postdata;
                              //                postdata.insert("code", m_code);
                              //                postdata.insert("client_id", "-----------client id-----------");
                              //                postdata.insert("p", "B2C_1_SIGN_IN");
                              //                postdata.insert("scope", m_authorizationCodeFlowPtr->scope());
                              //                QJsonDocument jsonLoginPostDoc;
                              //                jsonLoginPostDoc.setObject(postdata);
                              //                QByteArray deviceRegisterPostData = jsonLoginPostDoc.toJson();
                              //                QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager();
                              //                QNetworkRequest networkRequest;
                              //                networkRequest.setUrl(m_authorizationCodeFlowPtr->accessTokenUrl());
                              //                networkRequest.setRawHeader(QByteArray("Content-Length"), QByteArray::number(deviceRegisterPostData.size()));
                              //                networkRequest.setRawHeader(QByteArray("host"), m_authorizationCodeFlowPtr->accessTokenUrl().host().toUtf8());
                              //                networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
                              //                networkRequest.setRawHeader(QByteArray("grant_type"), "authorization_code");
                              //                QNetworkReply *reply = networkAccessManager->post(networkRequest,deviceRegisterPostData);
                              //                connect(networkAccessManager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> & )),
                              //                        this, SLOT(slot_onSslErrors(QNetworkReply*, const QList<QSslError> & )));
                              //                connect(reply, SIGNAL(finished()), this, SLOT(slot_accessTokenReply()));
                              //                reply->setSslConfiguration(QSslConfiguration::defaultConfiguration());
                          }
                      }
                  });
              
                  m_authorizationCodeFlowPtr->setAuthorizationUrl(QUrl("----------------- authorize url ---------------"));
                  m_authorizationCodeFlowPtr->setAccessTokenUrl(QUrl("------------ access token url -----------------"));
                  m_authorizationCodeFlowPtr->setClientIdentifier("------------client id-------------------");
                  m_authorizationCodeFlowPtr->setScope("openid");
                  const QUrl redirectUri = QUrl("http://127.0.0.1:8100/");
                  const auto port = static_cast<quint16>(redirectUri.port());
                  auto replyHandler = new QOAuthHttpServerReplyHandler(port, this);
                  m_authorizationCodeFlowPtr->setReplyHandler(replyHandler);
                  m_authorizationCodeFlowPtr->grant();
              }
              
              void AuthorizationCodeFlow::slot_accessTokenReply()
              {
                  QNetworkReply *reply = qobject_cast<QNetworkReply *>(QObject::sender());
                  QByteArray bytes = reply->readAll();
              }
              
              void AuthorizationCodeFlow::slot_onSslErrors(QNetworkReply* reply, const QList<QSslError> & error)
              {
                  Q_UNUSED(error);
                  reply->ignoreSslErrors();
              }

  • Lifetime Qt Champion

    Hi,

    I haven't used these class much beyond toying with the examples but why are you deriving your class from QOAuth2AuthorizationCodeFlow and then use one as member variable ?



  • @SGaist Aaah my bad.. I was trying thousand things to make it work and i got to put this here.. I will correct that, though still it doesn't work :(


  • Lifetime Qt Champion

    What service are you using for the authentication ?



  • @SGaist said in Access token for authorization code flow:

    What service are you using for the authentication ?

    We are using oauth2 services for authentication.


  • Lifetime Qt Champion

    That I have understood, what I meant was: are you using something that is known for that through eg GitHub, or do you have your own custom service ?



  • @SGaist Oops sorry, I didn't get your question.. We are using azure b2c services.


  • Lifetime Qt Champion

    Ok, then this StackOverflow answer might be of help.



  • Every service like azure, github, google, etc implements OAuth2 but with modifications so you have to implement those modifications also in Qt.