Qt OAuth2 Browser-Unterstützung

OAuth2 Benutzer-Agenten

Die OAuth2-Autorisierungsphase basiert auf einem User-Agent, der typischerweise entweder der Systembrowser oder ein eingebetteter User-Agent wie Qt WebEngine.

Die Wahl zwischen dem Systembrowser und einem eingebetteten User-Agent hängt von mehreren Faktoren ab. Im Folgenden werden einige wichtige Überlegungen beschrieben:

  • Der Systembrowser hat möglicherweise bereits aktive Anmeldungen des Benutzers. Daher kann die Benutzerauthentifizierung während der Autorisierungsphase unkomplizierter sein, da die vorhandene Anmeldung verwendet werden kann. Im Gegensatz dazu muss der Benutzer bei einem eingebetteten Benutzer-Agenten normalerweise eine neue Anmeldung vornehmen. Andererseits ist es nicht immer wünschenswert, eine Anmeldesitzung im Systembrowser zurückzulassen. Systembrowser können auch Anwendungsnutzungsdaten mit anderen Parteien teilen.
  • Der Systembrowser ist dem Benutzer in der Regel vertraut und bietet eine vertraute Benutzererfahrung für die Anmeldung. Andererseits kann ein eingebetteter Benutzer-Agent zwar ein weniger vertrautes Erscheinungsbild bieten, aber der Anwendungsentwickler kann die Anmeldeinteraktion als Teil des Anwendungsfensters einbetten, anstatt sie in einem separaten Browserfenster durchzuführen. Außerdem kann der Anwendungsentwickler das Schließen des eingebetteten User-Agents automatisieren, wenn er nicht mehr benötigt wird.
  • Systembrowser bieten dem Benutzer vertraute Sicherheitsdarstellungen wie die Adressleiste und die Zertifikatsüberprüfung. Diese sind bei einem eingebetteten Benutzer-Agenten möglicherweise nicht sichtbar. Außerdem können die Systembrowser die Sicherheitsfunktionen des zugrunde liegenden Betriebssystems besser nutzen.
  • Ein eingebetteter User-Agent hat potenziell Zugriff auf alle Sicherheitsdaten, die der Benutzer eingibt.
  • Nicht alle Plattformen bieten Unterstützung für die Handhabung von https oder benutzerdefinierten uri-scheme redirect URLs (siehe QOAuthUriSchemeReplyHandler). Bei diesen Plattformen kann ein eingebetteter Benutzer-Agent verwendet werden, um diese Einschränkung zu umgehen.
  • Die Einbindung eines eingebetteten Benutzer-Agenten als Teil der Anwendung ist in der Regel eine große Komponente, die den Speicherbedarf der Anwendung erhöht. Andererseits steht nicht in allen Anwendungsfällen ein Systembrowser zur Verfügung, oder die Anwendung verwendet bereits einen eingebetteten User-Agent für andere Zwecke.

In Anbetracht dieser Überlegungen wird die Verwendung des Systembrowsers für native Anwendungen empfohlen. Aber wie einige der oben genannten Punkte andeuten, kann es immer noch gültige Anwendungsfälle für die Verwendung eines eingebetteten Benutzer-Agenten geben.

Verwendung des Systembrowsers

Um den Systembrowser zu verwenden, muss er geöffnet und zu der von der Anwendung konfigurierten Autorisierungs-URL navigiert werden. Eine typische Verwendung sieht wie folgt aus:

connect(&m_oauth, &QAbstractOAuth::authorizeWithBrowser, this, &QDesktopServices::openUrl);

Der Code verbindet das Signal QAbstractOAuth::authorizeWithBrowser mit dem Slot QDesktopServices::openUrl. Dadurch wird der Systembrowser geöffnet, in dem der Benutzer die erforderliche Authentifizierung und Autorisierung durchführt. Die Anwendung oder die Qt-Bibliotheken haben keine direkte Kontrolle über den Systembrowser, und er bleibt normalerweise geöffnet, sobald die Autorisierung abgeschlossen ist.

Weitere Details und unterstützte Redirect-URL-Schemata mit Systembrowser finden Sie unter Qt OAuth2 Overview, QOAuthHttpServerReplyHandler und QOAuthUriSchemeReplyHandler.

Die Verwendung von Qt WebEngine

Qt WebEngine bietet eine Webbrowser-Engine, um Webinhalte direkt in die Qt-Anwendung einzubetten.

Zusammen mit den Hauptsteuerungsfunktionen bietet es einfach zu verwendende Ansichten für QtWidgets und QtQuick-Anwendungen. Diese Ansichten können als User-Agent in einer OAuth2-Autorisierung verwendet werden. Qt WebEngine ist ein großes und vielseitiges Modul, und der Schwerpunkt dieser Dokumentation liegt auf der Verwendung mit OAuth2-Autorisierung.

Es gibt viele Möglichkeiten, die Qt WebEngine als Teil der Anwendung einzubetten. Aus praktischer Sicht sind die wichtigsten Überlegungen folgende:

  • QtQuick vs. QtWidgets Anwendungen. Dies wirkt sich darauf aus, wie die notwendige Integration mit QtNetworkAuth Klassen eingerichtet wird.
  • Redirect URI Schema. Dies wirkt sich darauf aus, welche QtNetworkAuth Antwort-Handler-Klassen zu verwenden sind und wie (siehe Qt OAuth2 Overview).

QtQuick und QtWidgets Anwendungen

Qt WebEngine kann sowohl mit QtQuick- als auch mit QtWidgets-Anwendungen für die OAuth2-Autorisierung verwendet werden. Der Hauptunterschied besteht darin, wie die wenigen notwendigen Enabler eingerichtet werden.

Im Folgenden wird ein vereinfachtes QWebEngineView (QtWidget) Setup gezeigt. Die Fehlerbehandlung und jede potentielle Qt WebEngine Konfiguration wird der Kürze halber weggelassen.

Folgende Widgets vorausgesetzt:

QWebEngineView *webView = nullptr;
QMainWindow mainWindow;

Anstatt den Systembrowser zu öffnen, verwenden wir die QWebEngineView, um die Autorisierung durchzuführen:

connect(&m_oauth, &QAbstractOAuth::authorizeWithBrowser, this, [this](const QUrl &url) {
    mainWindow.show();
    webView->load(url);
    webView->show();
});

Sobald die Autorisierung abgeschlossen ist, schließen wir die Ansicht:

connect(&m_oauth, &QAbstractOAuth::granted, this, [this]() {
    // Here we use QNetworkRequestFactory to store the access token
    m_api.setBearerToken(m_oauth.token().toLatin1());
    m_handler->close();
    webView->close();
});

Für QtQuick-Anwendungen ist der Ablauf im Prinzip derselbe, aber anstelle des Widgets QWebEngineView verwenden wir das QML-Element WebEngineView:

WebEngineView {
    id: authorizationWebView
    anchors.fill: parent
    visible: false
}

In diesem vereinfachten Beispiel werden die benötigten APIs von der C++ Klasse

class HttpExample : public QObject
{
    Q_OBJECT
#ifdef QT_QML_LIB
    QML_NAMED_ELEMENT(OAuth2)
#endif
public:
    Q_INVOKABLE void authorize();

signals:
    void authorizationCompleted(bool success);
    void authorizeWithBrowser(const QUrl &url);

Diese werden dann auf der QML-Seite für den Aufruf von WebEngineView verwendet, um die Autorisierung zu handhaben:

onAuthorizeWithBrowser:
    (url) => {
        console.log("Starting authorization with WebView")
        authorizationWebView.url = url
        authorizationWebView.visible = true
    }
onAuthorizationCompleted:
    (success) => {
        console.log("Authorized: " + success);
        authorizationWebView.visible = false
    }

URI-Umleitungsschemata

Die Wahl des Redirect-URI-Schemas (http, https oder custom-uri ) hat Auswirkungen auf die Verwendung von Qt WebEngine.

http Loopback URIs

Mit http loopback redirect URI und QOAuthHttpServerReplyHandler funktioniert die Handhabung ähnlich wie beim Systembrowser. Qt WebEngine leitet die Autorisierung auf den Localhost-Server des Reply-Handlers um, ähnlich wie der Systembrowser.

Benutzerdefinierte Schema-URIs

Bei benutzerdefinierten Schema-URIs (wie com.example.myqtapp:/redirect) und QOAuthUriSchemeReplyHandler funktioniert der Ablauf ähnlich wie beim Systembrowser.

Der Hauptunterschied besteht darin, dass die Anwendung nicht ähnlich konfiguriert werden muss wie die Universal Links auf iOS/macOS oder App Links auf Android, wie in der Dokumentation QOAuthUriSchemeReplyHandler beschrieben.

m_handler.setRedirectUrl(QUrl{"com.example.myqtapp://oauth2redirect"_L1});
m_oauth.setReplyHandler(&m_handler);

connect(&m_oauth, &QAbstractOAuth::authorizeWithBrowser, this, [this](const QUrl &url) {
    mainWindow.show();
    webView->load(url);
    webView->show();
});
connect(&m_oauth, &QAbstractOAuth::granted, this, [this]() {
    // Here we use QNetworkRequestFactory to store the access token
    m_api.setBearerToken(m_oauth.token().toLatin1());
    m_handler.close();
    webView->close();
});

Technisch funktioniert das so, dass Qt WebEngine den QDesktopServices::openUrl() für unbehandelte URI-Schemata aufruft, dessen Gegenstück QOAuthUriSchemeReplyHandler zuhört.

https URIs

Bei https URIs und QOAuthUriSchemeReplyHandler ändert sich die Logik leicht. Ähnlich wie bei benutzerdefinierten URI-Schemata muss die Anwendung nicht konfiguriert werden, aber wir müssen die Umleitung am Ende der Autorisierungsphase an die Web-Engine weiterleiten.

connect(webView, &QWebEngineView::urlChanged, this, [this](const QUrl &url){
    m_handler.handleAuthorizationRedirect(url);
});

Dies ist notwendig, weil aus Qt WebEngine Sicht ist die Umleitungs-URL eine gültige https URL und wird standardmäßig versuchen, zu ihr zu navigieren.

Um solche Navigationsversuche und die versehentliche Offenlegung des Autorisierungscodes zu verhindern (denken Sie an den Fall, dass die Umleitungs-URL-Domäne nicht unter Ihrer Kontrolle steht), sollte eine aufwändigere Filterung verwendet werden. Auch die Verwendung von QOAuth2AuthorizationCodeFlow::PkceMethod wird dringend empfohlen, da sie die Auswirkungen von Autorisierungscode-Hijacking abschwächt.

Zum Beispiel:

connect(webView->page(), &QWebEnginePage::navigationRequested,
        this, [this](QWebEngineNavigationRequest &request) {
    if (request.navigationType() == QWebEngineNavigationRequest::RedirectNavigation
        && m_handler.handleAuthorizationRedirect(request.url())) {
        request.reject();
        webView->close();
    } else {
        request.accept();
    }
});

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.