Migrationsanleitung für Out-of-Band-Datenflüsse (OOB)

Ü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. Dieser Leitfaden hilft Ihnen, die erforderlichen Änderungen und Schritte für die erfolgreiche Migration vom OAuth-OOB-Flow (Out-of-Band) zu unterstützten Alternativen nachzuvollziehen.

Diese Maßnahme dient zum Schutz vor Phishing- und App-Imitationsangriffen bei der Interaktion mit den OAuth 2.0-Autorisierungsendpunkten von Google.

Was ist OOB?

OAuth Out-of-Band (OOB), auch als manuelle Copy-and-Paste-Option bezeichnet, ist ein Legacy-Ablauf, der für native Clients entwickelt wurde, die keinen Redirect-URI haben, um die Anmeldedaten zu akzeptieren, nachdem ein Nutzer einer OAuth-Zustimmungsanfrage zugestimmt hat. Der OOB-Ablauf birgt das Risiko von Remote-Phishing. Clients müssen zu einer alternativen Methode migrieren, um sich vor dieser Sicherheitslücke zu schützen.

Der OOB-Ablauf wird für alle Clienttypen eingestellt, d.h. für Webanwendungen, Android, iOS, Universal Windows Platform (UWP), Chrome-Apps, Fernseher und Geräte mit eingeschränkter Eingabe, 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: Nutzern wird möglicherweise eine Warnmeldung angezeigt, wenn nicht konforme OAuth-Anfragen gestellt werden.
  • 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).

Für nicht konforme Anfragen wird eine Fehlermeldung für Nutzer angezeigt. In der Nachricht wird 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 API Console registriert haben.

Der Migrationsprozess umfasst zwei Hauptschritte:
  1. Prüfen, ob Sie betroffen sind
  2. Wenn Sie betroffen sind, sollten Sie zu einer sichereren Alternative wechseln.

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 im Branding pageGoogle Cloud Console von OAuth 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-Ablauf verwendet

Prüfen Sie den App-Code oder den ausgehenden Netzwerkaufruf (falls Ihre App eine OAuth-Bibliothek verwendet), um festzustellen, ob die von Ihrer App ausgehende Google OAuth-Autorisierungsanfrage einen OOB-Weiterleitungs-URI-Wert verwendet.

Anwendungscode prüfen

Sehen Sie sich den Abschnitt Ihres Anwendungscodes an, in dem Sie Aufrufe an die Google OAuth-Autorisierungsendpunkte ausführen, und prüfen Sie, ob der Parameter redirect_uri einen der folgenden Werte hat:
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
Eine Beispielanfrage für den 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 Netzwerkanruf prüfen

Die Methode zum Untersuchen von Netzwerkanrufen variiert je nach Clienttyp Ihrer Anwendung.
Achten Sie bei der Überprüfung von Netzwerkanrufen auf Anfragen, die an die Google OAuth-Autorisierungsendpunkte gesendet werden, und prüfen Sie, ob der Parameter redirect_uri einen der folgenden Werte hat:
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
Eine Beispielanfrage für den 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 wechseln

Mobile Clients (Android / iOS)

Wenn Sie feststellen, dass Ihre App den OOB-Ablauf mit einem Android- oder iOS-OAuth-Clienttyp verwendet, sollten Sie zur Verwendung der empfohlenen SDKs (Android, iOS) migrieren.

Das SDK erleichtert den Zugriff auf Google APIs und verarbeitet alle Aufrufe der OAuth 2.0-Autorisierungsendpunkte von Google.

In den Dokumentationslinks unten 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 Google Identity Services Android-Bibliothek auf Google-APIs auf der Clientseite unter Android zugreifen.

  List 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 authorizationResult an die von Ihnen definierte Methode, um Inhalte im Drive-Ordner des Nutzers zu speichern. Das authorizationResult hat die Methode getAccessToken(), die das Zugriffstoken zurückgibt.

Serverseitiger (Offline-)Zugriff
Das folgende Beispiel zeigt, wie Sie serverseitig auf Google APIs auf Android zugreifen.
  List 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));

Die authorizationResult-Klasse hat die Methode getServerAuthCode(), die den Autorisierungscode zurückgibt, den Sie an Ihr Backend senden können, um ein Zugriffs- und Aktualisierungstoken zu erhalten.

Auf Google APIs in einer iOS-App zugreifen

Clientseitiger Zugriff

Das folgende Beispiel zeigt, wie Sie auf Google-APIs auf der Clientseite unter iOS 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. Dazu können Sie das Zugriffstoken entweder in den Header einer REST- oder gRPC-Anfrage (Authorization: Bearer ACCESS_TOKEN) einfügen oder den Fetcher-Autorisierer (GTMFetcherAuthorizationProtocol) mit der Google API-Clientbibliothek für Objective-C für REST verwenden.

In der Anleitung für den clientseitigen Zugriff erfahren Sie, wie Sie clientseitig auf Google-APIs zugreifen. wie Sie clientseitig auf Google-APIs zugreifen können.

Serverseitiger (Offline-)Zugriff
Im folgenden Beispiel wird gezeigt, 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
}

Leitfaden für den serverseitigen Zugriff

Chrome-App-Client

Wenn Sie feststellen, dass Ihre App den OOB-Ablauf im Chrome-App-Client verwendet, sollten Sie zur Chrome Identity API migrieren.

Im folgenden Beispiel wird gezeigt, wie Sie alle Nutzerkontakte ohne Verwendung eines OOB-Weiterleitungs-URI abrufen.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {

  
  // retrieve access token
  chrome.identity.getAuthToken({interactive: true}, function(token) {
  
  // ..........


  // the example below 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 Authentifizieren von Nutzern und Aufrufen von Google-Endpunkten mit der Chrome Identity API finden Sie im Leitfaden zur Chrome Identity API.

Webanwendung

Wenn Sie feststellen, dass Ihre App den OOB-Ablauf für eine Webanwendung verwendet, sollten Sie zu einer unserer Google API-Clientbibliotheken migrieren. Clientbibliotheken für verschiedene Programmiersprachen sind hier aufgeführt.

Die Bibliotheken erleichtern den Zugriff auf Google APIs und verarbeiten alle Aufrufe der 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 empfangen.
  • Konfigurieren Sie den Weiterleitungs-URI in der Clients page der Google Cloud Console.

Im folgenden Code-Snippet sehen Sie ein NodeJS-Beispiel für die Verwendung der Google Drive API, um die Google Drive-Dateien eines Nutzers serverseitig aufzulisten, ohne eine 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.
      });
    }
  }
}

Im Leitfaden für serverseitige Web-Apps erfahren Sie, wie Sie serverseitig auf Google APIs zugreifen.

Clientseitiger Zugriff

Das folgende Code-Snippet in JavaScript zeigt ein Beispiel für die Verwendung der Google API für den clientseitigen Zugriff auf die Kalenderereignisse eines Nutzers.


// 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(...);
}

Im Leitfaden für clientseitige Webanwendungen erfahren Sie, wie Sie clientseitig auf Google APIs zugreifen.

Desktop client

Wenn Sie feststellen, dass Ihre App den OOB-Ablauf auf einem Desktopclient verwendet, sollten Sie zur Verwendung des Ablaufs mit Loopback-IP-Adresse (localhost oder 127.0.0.1) migrieren.