Übersicht
Am 16. Februar 2022 haben wir angekündigt, dass wir Google OAuth-Interaktionen durch die Verwendung sichererer OAuth-Abläufe sicherer machen möchten. Diese Anleitung hilft Ihnen, die Änderungen und Schritte nachzuvollziehen, die zur Migration vom Out-of-Band-OAuth-Ablauf (OOB) zu unterstützten Alternativen erforderlich sind.
Diese Maßnahme dient dem Schutz vor Phishing- und App-Impersonation-Angriffen bei Interaktionen mit den OAuth 2.0-Autorisierungsendpunkten von Google.
Was ist OOB?
Out-of-Band (OOB) von OAuth, auch als manuelle Option zum Kopieren und Einfügen bezeichnet, ist ein Legacy-Ablauf, der für installierte Clients entwickelt wurde, die keinen Weiterleitungs-URI haben, um die Anmeldedaten zu akzeptieren, nachdem ein Nutzer eine OAuth-Zustimmungsanfrage genehmigt hat. Der OOB-Ablauf birgt ein Remote-Phishing-Risiko. Clients müssen zu einer alternativen Methode migrieren, um sich vor dieser Sicherheitslücke zu schützen.
Der OOB-Ablauf wird für alle Anwendungstypen eingestellt, d. h. Webanwendungen, Android, iOS, Universal Windows Platform (UWP), Chrome-Apps, Fernseher und Geräte mit eingeschränkter Eingabe sowie Desktop-Apps.
Wichtige Termine für die Einhaltung der Richtlinie
- 28. Februar 2022: Neue OAuth-Nutzung für den OOB-Vorgang blockiert
- 5. September 2022: Bei nicht konformen OAuth-Anfragen wird möglicherweise eine für Nutzer sichtbare Warnmeldung angezeigt.
- 3. Oktober 2022: Der OOB-Ablauf wird für OAuth-Clients eingestellt, die vor dem 28. Februar 2022 erstellt wurden.
- 31. Januar 2023: Alle vorhandenen Clients werden blockiert (einschließlich ausgenommener Clients).
Bei nicht konformen Anfragen wird eine für Nutzer sichtbare Fehlermeldung angezeigt. In der Nachricht wird den Nutzern mitgeteilt, dass die App blockiert ist. Außerdem wird die Support-E-Mail-Adresse angezeigt, die Sie auf dem OAuth-Zustimmungsbildschirm in der Google Cloud Console registriert haben.
Die Migration umfasst zwei Hauptschritte:
- Prüfen Sie, ob Sie betroffen sind.
- Migrieren Sie zu einer sichereren Alternative, wenn Sie betroffen sind.
Prüfen, ob Sie betroffen sind
Diese Einstellung gilt nur für Produktions-Apps, d. h. Apps, deren Veröffentlichungsstatus auf In Produktion festgelegt ist. Der Ablauf funktioniert weiterhin für Apps mit dem Veröffentlichungsstatus „Test“.
Prüfen Sie den Veröffentlichungsstatus auf der Seite „OAuth-Branding“ der Google Cloud Console und fahren Sie mit dem nächsten Schritt fort, wenn Sie den OOB-Ablauf in einem Projekt mit dem Veröffentlichungsstatus „In Produktion“ verwenden.
So ermitteln Sie, ob Ihre App den OOB-Vorgang verwendet
Prüfen Sie Ihren App-Code oder den ausgehenden Netzwerkaufruf (falls Ihre App eine OAuth-Bibliothek verwendet), um festzustellen, ob die von Ihrer App gestellte Google OAuth-Autorisierungsanfrage einen OOB-Weiterleitungs-URI-Wert verwendet.
Anwendungscode prüfen
Prüfen Sie den Abschnitt Ihres Anwendungscodes, in dem Sie Aufrufe an die Google OAuth-Autorisierungsendpunkte senden, und stellen Sie fest, ob der Parameter redirect_uri einen der folgenden Werte hat:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oob
Eine Beispielanfrage für einen OOB-Weiterleitungsablauf sieht so aus:
https://accounts.google.com/o/oauth2/v2/auth? response_type=code& scope=<SCOPES>& state=<STATE>& redirect_uri=urn:ietf:wg:oauth:2.0:oob& client_id=<CLIENT_ID>
Ausgehenden Netzwerkaufruf prüfen
Die Methode zum Prüfen von Netzwerkaufrufen hängt vom Anwendungstyp ab.
- Webanwendung – Netzwerkaktivität in Chrome prüfen
- Android – Netzwerkverkehr mit dem Netzwerk-Inspector prüfen
- Chrome-Apps
- Rufen Sie die Seite mit den Chrome-Erweiterungen auf.
- Klicken Sie rechts oben auf der Seite „Erweiterungen“ das Kästchen Entwicklermodus an.
- Wählen Sie die Erweiterung aus, die Sie beobachten möchten.
- Klicken Sie auf der Seite der Erweiterung im Bereich Ansichten prüfen auf den Link Hintergrundseite.
- Das Dialogfeld Entwicklertools wird geöffnet. Dort können Sie den Netzwerkverkehr auf dem Tab Netzwerk beobachten.
- iOS – HTTP-Traffic mit Instruments analysieren
- Desktop-Apps: Verwenden Sie ein Tool zur Netzwerkerfassung, das für das Betriebssystem verfügbar ist, für das die App entwickelt wurde.
Suchen Sie beim Prüfen von Netzwerkaufrufen nach Anfragen, die an die OAuth-Autorisierungsendpunkte von Google gesendet werden, und prüfen Sie, ob der Parameter redirect_uri einen der folgenden Werte hat:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oob
Eine Beispielanfrage für einen OOB-Weiterleitungsablauf sieht so aus:
https://accounts.google.com/o/oauth2/v2/auth? response_type=code& scope=<SCOPES>& state=<STATE>& redirect_uri=urn:ietf:wg:oauth:2.0:oob& client_id=<CLIENT_ID>
Zu einer sicheren Alternative migrieren
Mobile Clients (Android und iOS)
Wenn Sie feststellen, dass Ihre App den OOB-Vorgang mit einem Android- oder iOS-OAuth-Anwendungstyp verwendet, sollten Sie zu den empfohlenen SDKs (Android, iOS) migrieren.
Das SDK unterstützt Sie beim Zugriff auf Google APIs und verarbeitet alle Aufrufe an die OAuth 2.0-Autorisierungsendpunkte von Google.
Unter den folgenden Dokumentlinks finden Sie Informationen dazu, wie Sie mit den empfohlenen SDKs auf Google APIs zugreifen können, ohne einen OOB-Weiterleitungs-URI zu verwenden.
Auf Google APIs unter Android zugreifen
Clientseitiger Zugriff
Im folgenden Beispiel wird gezeigt, wie Sie mit der empfohlenen Android-Bibliothek für Google Identity Services auf der Clientseite unter Android auf Google APIs zugreifen.
List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA);
AuthorizationRequest authorizationRequest =
AuthorizationRequest.builder()
.setRequestedScopes(requestedScopes)
.build();
Identity.getAuthorizationClient(activity)
.authorize(authorizationRequest)
.addOnSuccessListener(
authorizationResult -> {
if (authorizationResult.hasResolution()) {
// Access needs to be granted by the user
PendingIntent pendingIntent =
authorizationResult.getPendingIntent();
try {
startIntentSenderForResult(
pendingIntent.getIntentSender(),
REQUEST_AUTHORIZE, null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Log.e(
TAG,
"Couldn't start Authorization UI: "
+ e.getLocalizedMessage());
}
} else {
// Access already granted, continue with user action
saveToDriveAppFolder(authorizationResult);
}
})
.addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
Übergeben Sie die authorizationResult an Ihre definierte Methode, um Inhalte im Drive-Ordner des Nutzers zu speichern. authorizationResult hat die Methode getAccessToken(), die das Zugriffstoken zurückgibt.
Serverseitiger (Offline-)Zugriff
Im folgenden Beispiel wird gezeigt, wie Sie auf Android-Geräten serverseitig auf Google APIs zugreifen.
List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder() .requestOfflineAccess(webClientId) .setRequestedScopes(requestedScopes) .build(); Identity.getAuthorizationClient(activity) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // Access needs to be granted by the user PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { startIntentSenderForResult( pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e( TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { String authCode = authorizationResult.getServerAuthCode(); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
authorizationResult enthält die Methode getServerAuthCode(), die den Autorisierungscode zurückgibt. Diesen kannst du an dein Backend senden, um ein Zugriffs- und Aktualisierungstoken zu erhalten.
In einer iOS-App auf Google APIs zugreifen
Clientseitiger Zugriff
Im folgenden Beispiel wird gezeigt, wie Sie auf iOS-Geräten clientseitig auf Google APIs zugreifen.
user.authentication.do { authentication, error in guard error == nil else { return } guard let authentication = authentication else { return } // Get the access token to attach it to a REST or gRPC request. let accessToken = authentication.accessToken // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for // use with GTMAppAuth and the Google APIs client library. let authorizer = authentication.fetcherAuthorizer() }
Verwenden Sie das Zugriffstoken, um die API aufzurufen. Fügen Sie dazu das Zugriffstoken in den Header einer REST- oder gRPC-Anfrage (Authorization: Bearer <var>ACCESS_TOKEN</var>) ein oder verwenden Sie den Fetcher-Authorizer (GTMFetcherAuthorizationProtocol) mit der Google APIs-Clientbibliothek für Objective-C für REST.
Informationen zum clientseitigen Zugriff auf Google APIs finden Sie im Leitfaden zum clientseitigen Zugriff.
Serverseitiger (Offline-)Zugriff
Das folgende Beispiel zeigt, wie Sie serverseitig auf Google APIs zugreifen, um einen iOS-Client zu unterstützen.
GIDSignIn.sharedInstance.signIn(
with: signInConfig, presenting: self
) { user, error in
guard error == nil else { return }
guard let user = user else { return }
// request a one-time authorization code that your server exchanges for
// an access token and refresh token
let authCode = user.serverAuthCode
}Informationen zum Zugriff auf Google APIs von der Serverseite finden Sie im Leitfaden für den serverseitigen Zugriff.
Chrome-App-Client
Wenn Sie feststellen, dass Ihre App den OOB-Ablauf auf dem Chrome-App-Client verwendet, sollten Sie zur Chrome Identity API migrieren.
Im folgenden Beispiel wird gezeigt, wie Sie alle Nutzerkontakte ohne OOB-Weiterleitungs-URI abrufen.
window.onload = function() { document.querySelector('button').addEventListener('click', function() { // retrieve access token chrome.identity.getAuthToken({interactive: true}, function(token) { // .......... // the following example shows how to use a retrieved access token with an // appropriate scope to call the Google People API contactGroups.get endpoint fetch( 'https://people.googleapis.com/v1/contactGroups/all' + '?maxMembers=20&key=API_KEY', init) .then((response) => response.json()) .then(function(data) { console.log(data) }); }); }); };
Weitere Informationen zum Zugriff auf authentifizierte Nutzer und zum Aufrufen von Google-Endpunkten mit der Chrome Identity API finden Sie im Leitfaden zur Chrome Identity API.
Webanwendung
Wenn Sie feststellen, dass Ihre Anwendung den OOB-Ablauf für eine Webanwendung verwendet, sollten Sie zu einer unserer Google API-Clientbibliotheken migrieren. Eine Liste der Google API-Clientbibliotheken für verschiedene Programmiersprachen finden Sie hier.
Die Bibliotheken vereinfachen den Zugriff auf Google APIs und verarbeiten alle Aufrufe an die Google-Endpunkte.
Serverseitiger (Offline-)Zugriff
Für den serverseitigen (Offline-)Zugriffsmodus müssen Sie Folgendes tun :
- Richten Sie einen Server ein und definieren Sie einen öffentlich zugänglichen Endpunkt (den Weiterleitungs-URI), um den Autorisierungscode zu erhalten.
- Konfigurieren Sie den Weiterleitungs-URI auf der Seite „Clients“ der Google Cloud Console.
Das folgende Code-Snippet zeigt ein NodeJS-Beispiel für die Verwendung der Google Drive API, um die Google Drive-Dateien eines Nutzers serverseitig aufzulisten, ohne einen OOB-Weiterleitungs-URI zu verwenden.
async function main() { const server = http.createServer(async function (req, res) { if (req.url.startsWith('/oauth2callback')) { let q = url.parse(req.url, true).query; if (q.error) { console.log('Error:' + q.error); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { // TODO(developer): Handle response / error. }); } } }
Informationen zum Zugriff auf Google APIs von der Serverseite finden Sie im Leitfaden für serverseitige Webanwendungen.
Clientseitiger Zugriff
Das folgende JavaScript-Code-Snippet zeigt ein Beispiel für die Verwendung der Google API, um clientseitig auf die Kalendertermine des Nutzers zuzugreifen.
// initTokenClient() initializes a new token client with your // web app's client ID and the scope you need access to const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', scope: 'https://www.googleapis.com/auth/calendar.readonly', // callback function to handle the token response callback: (tokenResponse) => { if (tokenResponse && tokenResponse.access_token) { gapi.client.setApiKey('YOUR_API_KEY'); gapi.client.load('calendar', 'v3', listUpcomingEvents); } }, }); function listUpcomingEvents() { gapi.client.calendar.events.list(...); }
Lesen Sie den Leitfaden für clientseitige Web-Apps, um zu erfahren, wie Sie von der Clientseite aus auf Google APIs zugreifen.
Desktop-Client
Wenn Sie feststellen, dass Ihre App den OOB-Ablauf auf einem Desktop-Client verwendet, sollten Sie zum Ablauf mit Loopback-IP-Adresse (localhost oder 127.0.0.1) migrieren.