Guide de migration du flux externe (OOB)

Présentation

Le 16 février 2022, nous avons annoncé notre intention de renforcer la sécurité des interactions OAuth Google en utilisant des flux OAuth plus sécurisés. Ce guide vous explique les changements nécessaires et la marche à suivre pour passer du flux OAuth hors bande (OOB) aux alternatives compatibles.

Cette initiative est une mesure de protection contre les attaques par hameçonnage et l'usurpation d'identité d'application lors des interactions avec les points de terminaison d'autorisation OAuth 2.0 de Google.

Qu'est-ce que le mode hors connexion ?

OAuth hors bande (OOB), également appelé option de copier-coller manuel, est un ancien flux développé pour prendre en charge les clients natifs qui ne disposent pas d'URI de redirection pour accepter les identifiants après qu'un utilisateur a approuvé une requête d'autorisation OAuth. Le flux hors bande présente un risque d'hameçonnage à distance. Les clients doivent migrer vers une autre méthode pour se protéger contre cette faille.

Le flux hors bande est en cours d'abandon pour tous les types de clients, à savoir les applications Web, Android, iOS, la plate-forme UWP (Universal Windows Platform), les applications Chrome, les téléviseurs et les appareils à entrée limitée, les applications de bureau.

Dates clés de conformité

  • 28 février 2022 : nouvelle utilisation d'OAuth bloquée pour le flux hors connexion
  • 5 septembre 2022 : un message d'avertissement destiné aux utilisateurs peut s'afficher pour les requêtes OAuth non conformes
  • 3 octobre 2022 : le flux hors connexion est obsolète pour les clients OAuth créés avant le 28 février 2022.
  • 31 janvier 2023 : tous les clients existants sont bloqués (y compris les clients exemptés)

Un message d'erreur s'affichera pour les requêtes non conformes. Le message indique aux utilisateurs que l'application est bloquée, tout en affichant l'adresse e-mail d'assistance que vous avez enregistrée sur l'écran de consentement OAuth dans la console Google APIs.

Le processus de migration comporte deux étapes principales :
  1. Déterminez si vous êtes concerné.
  2. Si vous êtes concerné, migrez vers une alternative plus sécurisée.

Déterminer si vous êtes concerné

Cette suppression ne s'applique qu'aux applications de production (applications dont l'état de publication est défini sur En production). Le flux continuera de fonctionner pour les applications dont l' état de publication est "Test".

Vérifiez l'état de publication dans la OAuth de la et passez à l'étape suivante si vous utilisez le flux hors bande dans un projet dont l'état de publication est "En production".

Déterminer si votre application utilise le flux hors bande

Inspectez le code de votre application ou l'appel réseau sortant (si votre application utilise une bibliothèque OAuth) pour déterminer si la requête d'autorisation Google OAuth que votre application effectue utilise une valeur d'URI de redirection hors bande.

Inspecter le code de votre application

Examinez la section de votre code d'application dans laquelle vous appelez les points de terminaison d'autorisation OAuth de Google et déterminez si le paramètre redirect_uri a l'une des valeurs suivantes :
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
Voici un exemple de requête de flux de redirection hors bande:
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>

Inspecter l'appel réseau sortant

La méthode d'inspection des appels réseau varie en fonction du type de client de votre application.
Lorsque vous inspectez les appels réseau, recherchez les requêtes envoyées aux points de terminaison d'autorisation Google OAuth et déterminez si le paramètre redirect_uri a l'une des valeurs suivantes :
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
Voici un exemple de requête de flux de redirection hors bande:
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>

Migrer vers une alternative sécurisée

Clients mobiles (Android / iOS)

Si vous déterminez que votre application utilise le flux hors connexion avec un type de client OAuth Android ou iOS, vous devez migrer vers les SDK recommandés (Android, iOS).

Le SDK facilite l'accès aux API Google et gère tous les appels aux points de terminaison d'autorisation OAuth 2.0 de Google.

Les liens vers la documentation ci-dessous fournissent des informations sur l'utilisation des SDK recommandés pour accéder aux API Google sans utiliser d'URI de redirection hors bande.

Accéder aux API Google sur Android

Accès côté client

L'exemple suivant montre comment accéder aux API Google côté client sur Android à l'aide de la bibliothèque Android Google Identity Services recommandée.

  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));

Transmettez authorizationResult à la méthode définie pour enregistrer le contenu dans le dossier Drive de l'utilisateur. authorizationResult dispose de la méthode getAccessToken() qui renvoie le jeton d'accès.

Accès côté serveur (hors connexion)
L'exemple suivant montre comment accéder aux API Google côté serveur sur Android.
  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));

authorizationResult dispose de la méthode getServerAuthCode() qui renvoie le code d'autorisation que vous pouvez envoyer à votre backend pour obtenir un jeton d'accès et d'actualisation.

Accéder aux API Google dans une application iOS

Accès côté client

L'exemple ci-dessous montre comment accéder aux API Google côté client sur iOS.

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()
}

Utilisez le jeton d'accès pour appeler l'API, en incluant le jeton d'accès dans l'en-tête d'une requête REST ou gRPC (Authorization: Bearer ACCESS_TOKEN), ou en utilisant l'autorisation du récupérateur (GTMFetcherAuthorizationProtocol) avec la bibliothèque cliente des API Google pour Objective-C pour REST.

Consultez le guide d'accès côté client pour savoir comment accéder aux API Google côté client. sur l'accès aux API Google côté client.

Accès côté serveur (hors connexion)
L'exemple ci-dessous montre comment accéder aux API Google côté serveur pour prendre en charge un client iOS.
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
}

Consultez le guide d'accès côté serveur pour savoir comment accéder aux API Google côté serveur.

Client d'application Chrome

Si vous déterminez que votre application utilise le flux hors connexion sur le client de l'application Chrome, vous devez passer à l' API Chrome Identity.

L'exemple ci-dessous montre comment obtenir tous les contacts de l'utilisateur sans utiliser d'URI de redirection hors bande.

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)
    });
   });
 });
};

Consultez le guide de l'API Chrome Identity pour en savoir plus sur l'accès aux utilisateurs authentifiés et l'appel des points de terminaison Google avec l'API Chrome Identity.

Application Web

Si vous déterminez que votre application utilise le flux hors bande pour une application Web, vous devez migrer vers l'une de nos bibliothèques clientes d'API Google. Vous trouverez la liste des bibliothèques clientes pour différents langages de programmation sur cette page.

Les bibliothèques facilitent l'accès aux API Google et gèrent tous les appels aux points de terminaison Google.

Accès côté serveur (hors connexion)
Le mode d'accès côté serveur (hors connexion) nécessite les étapes suivantes :
  • Déployez un serveur et définissez un point de terminaison accessible au public (l'URI de redirection) pour recevoir le code d'autorisation.
  • Configurez l' URI de redirection dans le du .

L'extrait de code ci-dessous montre un exemple NodeJS d'utilisation de l'API Google Drive pour lister les fichiers Google Drive d'un utilisateur côté serveur sans utiliser d'URI de redirection hors bande.

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

Consultez le guide de l'application Web côté serveur pour savoir comment accéder aux API Google côté serveur.

Accès côté client

L'extrait de code ci-dessous, en JavaScript, montre comment utiliser l'API Google pour accéder aux événements de l'agenda de l'utilisateur côté client.


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

Consultez le guide de l'application Web côté client pour savoir comment accéder aux API Google côté client.

Client pour ordinateur

Si vous déterminez que votre application utilise le flux OOB sur un client de bureau, vous devez passer au flux d'adresse IP de bouclage (localhost ou 127.0.0.1).