summaryrefslogtreecommitdiffstats
path: root/src/oauth/qoauth2authorizationcodeflow.cpp
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@qt.io>2024-08-01 14:59:13 +0300
committerJuha Vuolle <juha.vuolle@qt.io>2024-08-22 16:22:46 +0300
commitcbc09724824c2ae38c74ad5d5d4188168843a777 (patch)
tree4585fe1d3531b17890eaf1a0f7aa095922595a7e /src/oauth/qoauth2authorizationcodeflow.cpp
parent14f1aa2a9fd94ae7566a1bc6641bc3d8b952f935 (diff)
Encode 'state' parameter during authorization
Use encoding defined by RFC 6749 4.1.1 Authorization Request. The pre-existing implementation worked with internally generated random states, but had trouble especially with characters such as + and space ' ' which the user may set manually. I tested this against for major public Authorization Server providers, and with this patch they work with states like "foo %b+ar" (all of them don't work without this patch). Pick-to: 6.8 6.7 6.5 Fixes: QTBUG-104655 Change-Id: I849dd720c287e74f30be3fd7b1e631871ade9c12 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/oauth/qoauth2authorizationcodeflow.cpp')
-rw-r--r--src/oauth/qoauth2authorizationcodeflow.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/oauth/qoauth2authorizationcodeflow.cpp b/src/oauth/qoauth2authorizationcodeflow.cpp
index 2369fb8..acefb20 100644
--- a/src/oauth/qoauth2authorizationcodeflow.cpp
+++ b/src/oauth/qoauth2authorizationcodeflow.cpp
@@ -63,6 +63,23 @@ QOAuth2AuthorizationCodeFlowPrivate::QOAuth2AuthorizationCodeFlowPrivate(
responseType = QStringLiteral("code");
}
+static QString toUrlFormEncoding(const QString &source)
+{
+ // RFC 6749 Appendix B
+ // https://datatracker.ietf.org/doc/html/rfc6749#appendix-B
+ // Replace spaces with plus, while percent-encoding the rest
+ QByteArray encoded = source.toUtf8().toPercentEncoding(" ");
+ encoded.replace(" ", "+");
+ return QString::fromUtf8(encoded);
+}
+
+static QString fromUrlFormEncoding(const QString &source)
+{
+ QByteArray decoded = source.toUtf8();
+ decoded = QByteArray::fromPercentEncoding(decoded.replace("+"," "));
+ return QString::fromUtf8(decoded);
+}
+
void QOAuth2AuthorizationCodeFlowPrivate::_q_handleCallback(const QVariantMap &data)
{
Q_Q(QOAuth2AuthorizationCodeFlow);
@@ -78,7 +95,8 @@ void QOAuth2AuthorizationCodeFlowPrivate::_q_handleCallback(const QVariantMap &d
const QString error = data.value(Key::error).toString();
const QString code = data.value(Key::code).toString();
- const QString receivedState = data.value(Key::state).toString();
+ const QString receivedState = fromUrlFormEncoding(data.value(Key::state).toString());
+
if (error.size()) {
// RFC 6749, Section 5.2 Error Response
const QString uri = data.value(Key::errorUri).toString();
@@ -518,7 +536,7 @@ QUrl QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl(const QMultiMap<QString,
p.insert(Key::redirectUri, callback());
if (!d->requestedScope.isEmpty())
p.insert(Key::scope, d->requestedScope.join(" "_L1));
- p.insert(Key::state, state);
+ p.insert(Key::state, toUrlFormEncoding(state));
if (d->pkceMethod != PkceMethod::None) {
p.insert(Key::codeChallenge, d->createPKCEChallenge());
p.insert(Key::codeChallengeMethod,