Utilizzo di OAuth 2.0 per le applicazioni da server a server

Il sistema OAuth 2.0 di Google supporta le interazioni server-to-server come quelle tra un'applicazione web e un servizio Google. Per questo scenario è necessario un account di servizio, ovvero un account che appartiene alla tua applicazione anziché a un singolo utente finale. L'applicazione chiama le API di Google per conto dell'account di servizio. In questo modo, gli utenti non vengono coinvolti direttamente. Questo scenario è a volte chiamato "OAuth a due vie" o "2LO". Il termine correlato "OAuth a tre vie" si riferisce agli scenari in cui l'applicazione chiama le API di Google per conto degli utenti finali e in cui a volte è richiesto il consenso dell'utente.

In genere, un'applicazione utilizza un account di servizio quando utilizza le API di Google per lavorare con i propri dati anziché con quelli di un utente. Ad esempio, un'applicazione che utilizza Google Cloud Datastore per la persistenza dei dati userebbe un account di servizio per autenticare le sue chiamate all'API Google Cloud Datastore.

Gli amministratori di dominio Google Workspace possono anche concedere agli account di servizio l'autorità a livello di dominio di accedere ai dati utente per conto degli utenti del dominio.

Questo documento descrive come un'applicazione può completare il flusso OAuth 2.0 server-to-server utilizzando una libreria client delle API di Google (opzione consigliata) o HTTP.

Panoramica

Per supportare le interazioni server-to-server, devi prima creare un account di servizio per il progetto in API Console. Se vuoi accedere ai dati degli utenti nel tuo account Google Workspace, delega l'accesso a livello di dominio all'account di servizio.

Quindi, l'applicazione si prepara a effettuare chiamate API autorizzate utilizzando le credenziali dell'account di servizio per richiedere un token di accesso al server di autenticazione OAuth 2.0.

Infine, l'applicazione può utilizzare il token di accesso per chiamare le API di Google.

Creazione di un account di servizio

Le credenziali di un account di servizio includono un indirizzo email generato univoco e almeno una coppia di chiavi pubblica/privata. Se la delega a livello di dominio è abilitata, anche un ID client fa parte delle credenziali dell'account di servizio.

Se la tua applicazione viene eseguita su Google App Engine, un account di servizio viene configurato automaticamente quando crei il progetto.

Se la tua applicazione viene eseguita su Google Compute Engine, anche un account di servizio viene configurato automaticamente quando crei il progetto, ma devi specificare gli ambiti a cui deve accedere l'applicazione quando crei un'istanza di Google Compute Engine. Per maggiori informazioni, consulta Preparazione di un'istanza per l'utilizzo degli account di servizio.

Se la tua applicazione non viene eseguita su Google App Engine o Google Compute Engine, devi ottenere queste credenziali in Google API Console. Per generare le credenziali dell'account di servizio o per visualizzare le credenziali pubbliche che hai già generato:

Innanzitutto, crea un account di servizio:

  1. Apri il Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Fai clic su Crea account di servizio .
  4. In Dettagli dell'account di servizio , digita un nome, un ID e una descrizione per l'account di servizio, quindi fai clic su Crea e continua .
  5. Facoltativo: in Concedi a questo account di servizio l'accesso al progetto , seleziona i ruoli IAM da concedere all'account di servizio.
  6. Fare clic su Continua .
  7. Facoltativo: in Concedi agli utenti l'accesso a questo account di servizio , aggiungi gli utenti o i gruppi autorizzati a utilizzare e gestire l'account di servizio.
  8. Fai clic su Fatto .

Successivamente, crea una chiave dell'account di servizio:

  1. Fai clic sull'indirizzo email dell'account di servizio che hai creato.
  2. Fare clic sulla scheda Chiavi .
  3. Nell'elenco a discesa Aggiungi chiave , seleziona Crea nuova chiave .
  4. Fai clic su Crea .

La tua nuova coppia di chiavi pubblica/privata viene generata e scaricata sulla tua macchina; funge da unica copia della chiave privata. Sei responsabile di conservarlo in modo sicuro. Se perdi questa coppia di chiavi, dovrai generarne una nuova.

Puoi tornare alla API Console in qualsiasi momento per visualizzare l'indirizzo email, le fingerprint della chiave pubblica e altre informazioni o per generare ulteriori coppie di chiavi pubbliche/private. Per maggiori dettagli sulle credenziali dell'account di servizio in API Console, consulta Account di servizio nel file della guida API Console.

Prendi nota dell'indirizzo email dell'account di servizio e archivia il file della chiave privata dell'account di servizio in una posizione accessibile alla tua applicazione. L'applicazione ne ha bisogno per effettuare chiamate API autorizzate.

Delega dell'autorità a livello di dominio all'account di servizio

Utilizzando un account Google Workspace, un amministratore Workspace dell'organizzazione può autorizzare un'applicazione ad accedere ai dati utente di Workspace per conto degli utenti nel dominio Google Workspace. Ad esempio, un'applicazione che utilizza l'API Google Calendar per aggiungere eventi ai calendari di tutti gli utenti di un dominio Google Workspace userebbe un account di servizio per accedere all'API Google Calendar per conto degli utenti. L'autorizzazione di un account di servizio ad accedere ai dati per conto degli utenti di un dominio è a volte definita "delega dell'autorità a livello di dominio" a un account di servizio.

Per delegare l'autorità a livello di dominio a un account di servizio, un super amministratore del dominio Google Workspace deve completare i seguenti passaggi:

  1. Nella Console di amministrazione del tuo dominio Google Workspace, vai a Menu principale > Sicurezza > Accesso e controllo dei dati > Controlli API.
  2. Nel riquadro Delega a livello di dominio, seleziona Gestisci delega a livello di dominio.
  3. Fai clic su Aggiungi nuovo.
  4. Nel campo ID client, inserisci l'ID client dell'account di servizio. Puoi trovare l'ID client del tuo account di servizio in Service accounts page.
  5. Nel campo Ambiti OAuth (delimitati da virgole), inserisci l'elenco degli ambiti a cui deve essere concesso l'accesso all'applicazione. Ad esempio, se la tua applicazione richiede l'accesso completo a livello di dominio all'API Google Drive e all'API Google Calendar, inserisci: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. Fai clic su Autorizza.

La tua applicazione ha ora l'autorità per effettuare chiamate API in qualità di utenti nel tuo dominio Workspace (per "assumere l'identità degli utenti"). Quando ti prepari a effettuare queste chiamate API delegate, dovrai specificare esplicitamente l'utente da impersonare.

Preparazione per l'esecuzione di una chiamata API delegata

Java

Dopo aver ottenuto l'indirizzo email del client e la chiave privata da API Console, utilizza la libreria client delle API di Google per Java per creare un oggetto GoogleCredential dalle credenziali dell'account di servizio e dagli ambiti a cui deve accedere la tua applicazione. Ad esempio:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Se stai sviluppando un'app su Google Cloud Platform, puoi utilizzare le credenziali predefinite dell'applicazione, che possono semplificare il processo.

Delega l'autorità a livello di dominio

Se hai delegato l'accesso a livello di dominio all'account di servizio e vuoi impersonare un account utente, specifica l'indirizzo email dell'account utente con il metodo createDelegated dell'oggetto GoogleCredential. Ad esempio:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("workspace-user@example.com");

Il codice riportato sopra utilizza l'oggetto GoogleCredential per chiamare il relativo metodo createDelegated(). L'argomento del metodo createDelegated() deve essere un utente appartenente al tuo account Workspace. Il codice che effettua la richiesta utilizzerà questa credenziale per chiamare le API di Google utilizzando il tuo account di servizio.

Python

Dopo aver ottenuto l'indirizzo email del client e la chiave privata da API Console, utilizza la libreria client delle API di Google per Python per completare i seguenti passaggi:

  1. Crea un oggetto Credentials con le credenziali dell'account di servizio e gli ambiti a cui la tua applicazione deve accedere. Ad esempio:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Se stai sviluppando un'app su Google Cloud Platform, puoi utilizzare le credenziali predefinite dell'applicazione, che possono semplificare il processo.

  2. Delega l'autorità a livello di dominio

    Se hai delegato l'accesso a livello di dominio all'account di servizio e vuoi impersonare un account utente, utilizza il metodo with_subject di un oggetto ServiceAccountCredentials esistente. Ad esempio:

    delegated_credentials = credentials.with_subject('user@example.org')

Utilizza l'oggetto Credenziali per chiamare le API di Google nella tua applicazione.

HTTP/REST

Dopo aver ottenuto l'ID client e la chiave privata da API Console, l'applicazione deve completare i seguenti passaggi:

  1. Crea un token web JSON (JWT, pronunciato "jot"), che includa un'intestazione, un set di attestazioni e una firma.
  2. Richiedi un token di accesso al server di autorizzazione OAuth 2.0 di Google.
  3. Gestisci la risposta JSON restituita da Authorization Server.

Le sezioni seguenti descrivono come completare questi passaggi.

Se la risposta include un token di accesso, puoi utilizzarlo per chiamare un'API di Google. Se la risposta non include un token di accesso, la richiesta di JWT e token potrebbe non essere formata correttamente o l'account di servizio potrebbe non avere l'autorizzazione per accedere agli ambiti richiesti.

Quando il token di accesso scade, l'applicazione genera un altro JWT, lo firma e richiede un altro token di accesso.

L'applicazione server utilizza un JWT per richiedere un token al server di autorizzazione di Google, quindi utilizza il token per chiamare un endpoint API di Google. Non è coinvolto alcun utente finale.

Il resto di questa sezione descrive le specifiche della creazione di un JWT, della firma del JWT, della richiesta del token di accesso e della gestione della risposta.

Creazione di un JWT

Un JWT è composto da tre parti: un'intestazione, un set di attestazioni e una firma. L'insieme di intestazioni e attestazioni sono oggetti JSON. Questi oggetti JSON sono serializzati in byte UTF-8, quindi vengono codificati utilizzando la codifica Base64url. Questa codifica offre resilienza contro le modifiche alla codifica dovute a ripetute operazioni di codifica. L'intestazione, il set di attestazioni e la firma sono concatenati da un punto (.).

Un JWT è composto come segue:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

La stringa di base per la firma è la seguente:

{Base64url encoded header}.{Base64url encoded claim set}
Forma l'intestazione JWT

L'intestazione è composta da tre campi che indicano l'algoritmo di firma, il formato dell'asserzione e l'[ID chiave della chiave dell'account di servizio](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) utilizzato per firmare il JWT. L'algoritmo e il formato sono obbligatori e ogni campo ha un solo valore. Man mano che vengono aggiunti altri algoritmi e formati, questa intestazione cambierà di conseguenza. L'ID chiave è facoltativo e, se viene specificato un ID chiave errato, GCP proverà tutte le chiavi associate all'account di servizio per verificare il token e lo rifiuta se non viene trovata alcuna chiave valida. Google si riserva il diritto di rifiutare i token con ID chiave errati in futuro.

Gli account di servizio si basano sull'algoritmo RSA SHA-256 e sul formato del token JWT. Di conseguenza, la rappresentazione JSON dell'intestazione è la seguente:

{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}

La rappresentazione Base64url di questo è la seguente:

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Creazione dell'insieme di rivendicazioni JWT

Il set di attestazioni JWT contiene informazioni sul JWT, tra cui le autorizzazioni richieste (ambiti), la destinazione del token, l'emittente, l'ora di emissione e la durata di quest'ultimo. La maggior parte dei campi è obbligatoria. Come l'intestazione JWT, il set di attestazioni JWT è un oggetto JSON e viene utilizzato nel calcolo della firma.

Rivendicazioni obbligatorie

Di seguito sono riportate le rivendicazioni obbligatorie nell'insieme di rivendicazioni JWT. Le rivendicazioni possono essere mostrate in qualsiasi ordine nella serie di rivendicazioni.

Nome Descrizione
iss L'indirizzo email dell'account di servizio.
scope Un elenco delimitato da spazi delle autorizzazioni richieste dall'applicazione.
aud Un descrittore del target previsto dell'asserzione. Quando si effettua una richiesta di token di accesso, questo valore è sempre https://oauth2.googleapis.com/token.
exp La scadenza dell'asserzione, specificata in secondi dalle ore 00:00:00 UTC, 1° gennaio 1970. Questo valore ha un massimo di 1 ora dall'ora di emissione.
iat L'ora in cui è stata emessa l'asserzione, specificata in secondi dalle 00:00:00 UTC del 1° gennaio 1970.

Di seguito è riportata la rappresentazione JSON dei campi obbligatori in un set di rivendicazioni JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Rivendicazioni aggiuntive

In alcuni casi aziendali, un'applicazione può utilizzare la delega a livello di dominio per agire per conto di un determinato utente di un'organizzazione. L'autorizzazione a eseguire questo tipo di furto d'identità deve essere concessa prima che un'applicazione possa impersonare un utente e in genere è gestita da un super amministratore. Per maggiori informazioni, consulta Controllare l'accesso all'API con la delega a livello di dominio.

Per ottenere un token di accesso che conceda a un'applicazione l'accesso delegato a una risorsa, includi l'indirizzo email dell'utente nella rivendicazione JWT impostata come valore del campo sub.

Nome Descrizione
sub L'indirizzo email dell'utente per cui l'applicazione richiede l'accesso delegato.

Se un'applicazione non dispone dell'autorizzazione per impersonare un utente, la risposta a una richiesta di token di accesso che include il campo sub sarà un errore.

Di seguito è riportato un esempio di set di attestazioni JWT che include il campo sub:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Codifica dell'insieme di attestazioni JWT

Come l'intestazione JWT, il set di attestazioni JWT deve essere serializzato in formato UTF-8 e con codifica Base64url. Di seguito è riportato un esempio di rappresentazione JSON di un set di attestazioni JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Calcolo della firma

JWS (JSON Web Signature) è la specifica che guida i meccanismi per la generazione della firma per il JWT. L'input per la firma è l'array di byte dei seguenti contenuti:

{Base64url encoded header}.{Base64url encoded claim set}

Per calcolare la firma è necessario utilizzare l'algoritmo di firma nell'intestazione JWT. L'unico algoritmo di firma supportato dal server di autorizzazione OAuth 2.0 di Google è RSA che utilizza l'algoritmo di hashing SHA-256. Questo valore è espresso come RS256 nel campo alg nell'intestazione JWT.

Firma la rappresentazione UTF-8 dell'input utilizzando SHA256withRSA (noto anche come RSASSA-PKCS1-V1_5-SIGN con la funzione hash SHA-256) con la chiave privata ottenuta da Google API Console. L'output sarà un array di byte.

La firma deve quindi essere codificata in Base64url. L'intestazione, il set di attestazioni e la firma sono concatenati da un punto (.). Il risultato è il JWT. Deve essere il seguente (interruzioni di riga aggiunte per maggiore chiarezza):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Di seguito è riportato un esempio di codifica JWT precedente alla codifica Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Di seguito è riportato un esempio di un JWT che è stato firmato ed è pronto per la trasmissione:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Esecuzione della richiesta del token di accesso

Dopo aver generato il JWT firmato, un'applicazione può utilizzarlo per richiedere un token di accesso. Questa richiesta del token di accesso è una richiesta POST HTTPS e il corpo è codificato come URL. L'URL è mostrato di seguito:

https://oauth2.googleapis.com/token

I seguenti parametri sono obbligatori nella richiesta HTTPS POST:

Nome Descrizione
grant_type Utilizza la seguente stringa, con codifica URL secondo necessità: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion JWT, inclusa la firma.

Di seguito è riportato un dump non elaborato della richiesta HTTPS POST utilizzata in una richiesta di token di accesso:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Di seguito è riportata la stessa richiesta, utilizzando curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Gestione della risposta

Se la richiesta JWT e del token di accesso sono formattate correttamente e l'account di servizio dispone dell'autorizzazione per eseguire l'operazione, la risposta JSON dal server di autorizzazione includerà un token di accesso. Di seguito è riportato un esempio di risposta:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

I token di accesso possono essere riutilizzati durante la finestra di durata specificata dal valore expires_in.

Chiamata alle API di Google

Java

Utilizza l'oggetto GoogleCredential per chiamare le API di Google completando i seguenti passaggi:

  1. Crea un oggetto di servizio per l'API che vuoi chiamare utilizzando l'oggetto GoogleCredential. Ad esempio:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Effettua le richieste al servizio API utilizzando l'interfaccia fornita dall'oggetto di servizio. Ad esempio, per elencare le istanze dei database Cloud SQL nel progetto emozionante-example-123:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Utilizza l'oggetto Credentials autorizzato per chiamare le API di Google completando i seguenti passaggi:

  1. Crea un oggetto di servizio per l'API che vuoi chiamare. Per creare un oggetto di servizio, puoi chiamare la funzione build con il nome e la versione dell'API e l'oggetto Credentials autorizzato. Ad esempio, per chiamare la versione 1beta3 dell'API Cloud SQL Administration:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. Effettua le richieste al servizio API utilizzando l'interfaccia fornita dall'oggetto di servizio. Ad esempio, per elencare le istanze dei database Cloud SQL nel progetto emozionante-example-123:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Dopo che l'applicazione ha ottenuto un token di accesso, puoi utilizzarlo per effettuare chiamate a un'API di Google per conto di un determinato account di servizio o account utente, se sono stati concessi gli ambiti di accesso richiesti dall'API. A questo scopo, includi il token di accesso in una richiesta all'API includendo un parametro di query access_token o un valore Bearer di intestazione HTTP Authorization. Quando possibile, è preferibile utilizzare l'intestazione HTTP, perché le stringhe di query tendono a essere visibili nei log del server. Nella maggior parte dei casi, puoi utilizzare una libreria client per configurare le chiamate alle API di Google (ad esempio, quando chiami l'API Drive Files).

Puoi provare tutte le API di Google e visualizzarne gli ambiti nello spazio pubblico OAuth 2.0.

Esempi di GET HTTP

Una chiamata all'endpoint drive.files (l'API Drive Files) utilizzando l'intestazione HTTP Authorization: Bearer potrebbe avere il seguente aspetto. Tieni presente che devi specificare il tuo token di accesso:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Ecco una chiamata alla stessa API per l'utente autenticato utilizzando il parametro della stringa di query access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Esempi di curl

Puoi testare questi comandi con l'applicazione a riga di comando curl. Ecco un esempio che utilizza l'opzione dell'intestazione HTTP (opzione preferita):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

In alternativa, l'opzione del parametro della stringa di query:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Quando scadono i token di accesso

I token di accesso emessi dal server di autorizzazione OAuth 2.0 di Google scadono dopo la durata specificata dal valore expires_in. Quando un token di accesso scade, l'applicazione deve generare un altro JWT, firmarlo e richiedere un altro token di accesso.

Codici di errore JWT

Campo error Campo error_description Significato Come risolvere
unauthorized_client Unauthorized client or scope in request. Se stai tentando di utilizzare la delega a livello di dominio, l'account di servizio non è autorizzato nella Console di amministrazione del dominio dell'utente.

Assicurati che l'account di servizio sia autorizzato nella pagina Delega a livello di dominio della Console di amministrazione per l'utente nel campo sub attestazione.

In genere sono necessari alcuni minuti, ma potrebbero essere necessarie fino a 24 ore prima che l'autorizzazione si propaghi a tutti gli utenti nel tuo Account Google.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Un account di servizio è stato autorizzato utilizzando l'indirizzo email del client anziché l'ID client (numerico) nella Console di amministrazione. Nella pagina Delega a livello di dominio della Console di amministrazione, rimuovi il client e aggiungilo nuovamente con l'ID numerico.
access_denied (qualsiasi valore) Se utilizzi la delega a livello di dominio, uno o più ambiti richiesti non sono autorizzati nella Console di amministrazione.

Assicurati che l'account di servizio sia autorizzato nella pagina Delega a livello di dominio della Console di amministrazione per l'utente nel campo (campo) sub e che includa tutti gli ambiti che richiedi nella rivendicazione scope del JWT.

In genere sono necessari alcuni minuti, ma potrebbero essere necessarie fino a 24 ore prima che l'autorizzazione si propaghi a tutti gli utenti nel tuo Account Google.

admin_policy_enforced (qualsiasi valore) L'Account Google non è in grado di autorizzare uno o più ambiti richiesti a causa delle norme dell'amministratore di Google Workspace.

Consulta l'articolo del Centro assistenza per amministratori di Google Workspace Specificare quali app di terze parti e interne possono accedere ai dati di Google Workspace per maggiori informazioni su come un amministratore può limitare l'accesso a tutti gli ambiti o a tutti gli ambiti sensibili e con restrizioni finché l'accesso non viene concesso esplicitamente all'ID client OAuth.

invalid_client (qualsiasi valore)

Il client OAuth o il token JWT non sono validi o sono configurati in modo errato.

Per maggiori dettagli, consulta la descrizione dell'errore.

Assicurati che il token JWT sia valido e contenga attestazioni corrette.

Verifica che il client OAuth e l'account di servizio siano configurati correttamente e che l'indirizzo email utilizzato sia corretto.

Verifica che il token JWT sia corretto e che sia stato emesso per l'ID client nella richiesta.

invalid_grant Not a valid email. L'utente non esiste. Verifica che l'indirizzo email nel (campo) della rivendicazione sub sia corretto.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Solitamente, significa che l'ora del sistema locale non è corretta. Potrebbe verificarsi anche se il valore exp supera i 65 minuti nel futuro dal valore iat o se il valore exp è inferiore a quello di iat.

Assicurati che l'orologio del sistema in cui viene generato il JWT sia corretto. Se necessario, sincronizza l'ora con Google NTP.

invalid_grant Invalid JWT Signature.

L'asserzione JWT è firmata con una chiave privata non associata all'account di servizio identificato nell'email del client o la chiave utilizzata è stata eliminata, disabilitata o scaduta.

In alternativa, l'asserzione JWT potrebbe essere codificata in modo errato. Deve essere codificata in Base64, senza ritorni a capo o segni di uguale di spaziatura interna.

Decodifica l'insieme di rivendicazioni JWT e verifica che la chiave che ha firmato l'asserzione sia associata all'account di servizio.

Prova a utilizzare una libreria OAuth fornita da Google per assicurarti che il JWT venga generato correttamente.

invalid_scope Invalid OAuth scope or ID token audience provided. Non sono stati richiesti ambiti (elenco vuoto degli ambiti) o uno degli ambiti richiesti non esiste (ovvero non è valido).

Assicurati che l'attestazione (campo) scope del JWT sia compilata e confronta gli ambiti che contiene con gli ambiti documentati per le API che vuoi utilizzare, per assicurarti che non siano presenti errori di battitura.

Tieni presente che l'elenco degli ambiti nell'attestazione scope deve essere separato da spazi, non da virgole.

disabled_client The OAuth client was disabled. La chiave utilizzata per firmare l'asserzione JWT è disabilitata.

Vai a Google API Consolee, in IAM e amministrazione > Account di servizio, abilita l'account di servizio che contiene l'"ID chiave" utilizzato per firmare l'asserzione.

org_internal This client is restricted to users within its organization. L'ID client OAuth nella richiesta fa parte di un progetto che limita l'accesso agli Account Google in una specifica organizzazione Google Cloud.

Utilizza un account di servizio dell'organizzazione per l'autenticazione. Conferma la configurazione del tipo di utente per la tua applicazione OAuth.

Addendum: autorizzazione dell'account di servizio senza OAuth

Con alcune API di Google, puoi effettuare chiamate API autorizzate utilizzando un JWT firmato direttamente come token di connessione, anziché come token di accesso OAuth 2.0. Quando questo è possibile, puoi evitare di dover effettuare una richiesta di rete al server di autorizzazione di Google prima di effettuare una chiamata API.

Se l'API che vuoi chiamare ha una definizione di servizio pubblicata nel repository GitHub delle API di Google, puoi effettuare chiamate API autorizzate utilizzando un JWT anziché un token di accesso. Per farlo:

  1. Crea un account di servizio come descritto sopra. Assicurati di conservare il file JSON che ricevi al momento della creazione dell'account.
  2. Utilizzando qualsiasi libreria JWT standard, ad esempio quella disponibile in jwt.io, crea un JWT con un'intestazione e un payload come nell'esempio seguente:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Per il campo kid nell'intestazione, specifica l'ID della chiave privata del tuo account di servizio. Puoi trovare questo valore nel campo private_key_id del file JSON del tuo account di servizio.
    • Per i campi iss e sub, specifica l'indirizzo email dell'account di servizio. Puoi trovare questo valore nel campo client_email del file JSON del tuo account di servizio.
    • Per il campo aud, specifica l'endpoint API. Ad esempio: https://SERVICE.googleapis.com/.
    • Per il campo iat, specifica l'ora attuale di Unix, mentre per il campo exp, specifica l'ora esattamente 3600 secondi dopo, quando scadrà il JWT.

Firma il JWT con RSA-256 utilizzando la chiave privata che si trova nel file JSON dell'account di servizio.

Ad esempio:

Java

Utilizzando google-api-java-client e java-jwt:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

Con PyJWT:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Chiama l'API utilizzando il JWT firmato come token di connessione:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com