Scopri come richiamare le funzioni Cloud Functions autenticate

1. Introduzione

Panoramica

Cloud Functions è una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico che possono essere attivate tramite HTTPS o che possono rispondere a CloudEvents senza la necessità di gestire un ambiente server o di runtime.

Esistono due approcci principali per controllare le chiamate a Cloud Functions: proteggere l'accesso in base all'identità e proteggere l'accesso mediante i controlli dell'accesso basati sulla rete. Questo codelab si concentra sul primo approccio e ti guida in tre scenari per proteggere l'accesso in base all'identità per richiamare una funzione:

  1. Utilizza il token di identità gcloud per richiamare una funzione per lo sviluppo locale scopi di test
  2. Rappresenta un account di servizio durante lo sviluppo e il test in locale per utilizzare le stesse credenziali dell'ambiente di produzione
  3. Utilizza le librerie client di Google per gestire l'autenticazione nelle API Google Cloud, ad esempio Quando un servizio deve richiamare una funzione

Cosa imparerai a fare

  • Come configurare l'autenticazione su una funzione Cloud Functions e verificare che l'autenticazione sia stata configurata correttamente
  • Richiama una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
  • Creare un account di servizio e assegnargli il ruolo appropriato per richiamare una funzione
  • Come impersonare un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione

2. Configurazione e requisiti

Prerequisiti

  • Hai eseguito l'accesso alla console Cloud
  • In precedenza hai eseguito il deployment di una funzione Cloud Functions attivata da HTTP di 2a generazione
  • (Facoltativo) Per il terzo scenario, questo codelab utilizza Node.js e npm come esempio, ma puoi utilizzare qualsiasi runtime supportato dalle librerie client di Google Auth.

Attiva Cloud Shell

  1. Dalla console Cloud, fai clic su Attiva Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Se è la prima volta che avvii Cloud Shell, ti verrà mostrata una schermata intermedia che descrive di cosa si tratta. Se ti è stata presentata una schermata intermedia, fai clic su Continua.

9c92662c6a846a5c.png

Il provisioning e la connessione a Cloud Shell dovrebbero richiedere solo qualche istante.

9f0e51b578fecce5.png

Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Gran parte, se non tutto, del lavoro in questo codelab può essere svolto con un browser.

Una volta stabilita la connessione a Cloud Shell, dovresti vedere che hai eseguito l'autenticazione e che il progetto è impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per confermare che il comando gcloud è a conoscenza del tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Crea e testa una funzione Cloud Functions autenticata

Questo codelab segue le stesse istruzioni della guida rapida della console per Cloud Functions, con un'eccezione degna di nota: la funzione richiede l'autenticazione.

Richiedere l'autenticazione significa che il principio che richiama la funzione deve avere i ruoli Invoker di Cloud Functions (e Invoker di Cloud Run per la 2a generazione); altrimenti la funzione restituirà un errore 403 Forbidden. Questo codelab mostrerà come concedere i ruoli Invoker appropriati a un principio.

Crea la funzione autenticata

Ecco i passaggi per utilizzare la console Cloud:

  1. Vai alla pagina Panoramica di Cloud Functions e fai clic su Crea funzione
  2. Nell'opzione Ambiente, seleziona 2a generazione.
  3. Assegna alla funzione il nome my-authenticated-function.
  4. Nel campo Autenticazione, lascia il valore predefinito Richiedi autenticazione

936eee0d5930d12b.png

  1. Fai clic su Avanti.
  2. Per questo codelab, puoi scegliere qualsiasi lingua
  3. Poi fai clic su Esegui il deployment.

Il deployment della funzione richiede circa 1 minuto.

Configura le variabili di ambiente locali per i comandi gcloud semplificati

Innanzitutto, creerai alcune variabili di ambiente per migliorare la leggibilità dei comandi gcloud utilizzati in questo codelab.

Dovrai specificare la regione per la funzione. In questo esempio viene utilizzato us-central1.

REGION="us-central1"

e poi salvare l'URL della funzione come variabile di ambiente da utilizzare in seguito.

PROJECT_ID=$(gcloud config get-value project)
FUNCTION_URL="$(gcloud functions describe my-authenticated-function --gen2 --region us-central1 --format='get(serviceConfig.uri)')"

Verifica che la funzione richieda l'autenticazione tentando di richiamare come chiamante anonimo

Richiami la funzione senza autenticazione per verificare che tu riceva un errore 403 previsto.

Da una riga di comando, esegui questo comando curl:

curl $FUNCTION_URL

Vedrai questo risultato:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/</code> from this server.</h2>
<h2></h2>
</body></html>

Ora puoi esaminare tre scenari in cui puoi richiamare la funzione fornendo l'autenticazione.

4. Scenario 1: utilizzo del token di identità gcloud

In qualità di sviluppatore, vorrai testare la funzione mentre la stai sviluppando a livello locale. In questa sezione verrà eseguito un rapido test per verificare che la funzione sia correttamente autenticata utilizzando la tua identità.

Verifica di aver eseguito l'autenticazione tramite gcloud eseguendo questo comando:

gcloud auth list

Dovresti vedere un asterisco accanto alla tua identità attiva, ad esempio:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Una volta verificato di utilizzare l'identità corretta, salverai l'email dell'account in una variabile di ambiente.

ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")

Nella documentazione è possibile trovare ulteriori informazioni sulla configurazione di gcloud init e su gcloud auth login.

Successivamente, richiama la funzione e passala il token di identità.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"

Ora vedrai il risultato:

Hello World!

Risoluzione dei problemi

Se ricevi un errore 403 Forbidden, assicurati che l'identità abbia il ruolo Invoker di Cloud Functions o il ruolo Invoker di Cloud Run per le funzioni di 2a generazione. Puoi utilizzare la console IAM per verificare i ruoli assegnati a un'entità.

Sebbene l'utilizzo del tuo token di identità sia un modo rapido per testare la funzione durante lo sviluppo, il chiamante della funzione autenticata avrà bisogno dei ruoli appropriati; altrimenti il chiamante riceverà un errore 403: accesso negato.

Ti consigliamo di seguire il principio del privilegio minimo limitando il numero di identità e account di servizio che dispongono di ruoli per richiamare la funzione.

creando un nuovo account di servizio e assegnandogli i ruoli necessari.

5. Scenario 2: rubare l'identità di un account di servizio

In questo scenario, impersonerai (ossia assumerai le autorizzazioni di) un account di servizio per richiamare una funzione durante lo sviluppo e il test in locale. Se usi l'identità di un account di servizio, puoi testare la tua funzione con le stesse credenziali dell'account di produzione.

In questo modo non solo verificherai i ruoli, ma seguirai anche il principio del privilegio minimo, evitando di concedere il ruolo Invoker di funzioni Cloud ad altre identità solo per scopi di test locali.

Ai fini di questo codelab, creerai un nuovo account di servizio che disponga solo dei ruoli per richiamare la funzione che hai creato in questo codelab.

Crea un nuovo account di servizio

Per prima cosa, creerai un paio di variabili di ambiente aggiuntive per rappresentare gli account di servizio utilizzati nei comandi gcloud.

SERVICE_ACCOUNT_NAME="invoke-functions-codelab"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

Quindi, dovrai creare l'account di servizio.

gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
  --display-name="Cloud Function Authentication codelab"

E concedi il ruolo Invoker della funzione Cloud Functions dell'account di servizio.

gcloud functions add-iam-policy-binding my-authenticated-function \
  --region=us-central1 --gen2 \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/cloudfunctions.invoker'

Richiama la funzione impersonando l'account di servizio

A questo scopo, ruberai l'identità dell'account di servizio appena creato ottenendo il relativo token ID.

Aggiungi i ruoli richiesti per la rappresentazione

Per impersonare un account di servizio, l'account utente deve disporre del ruolo Creatore token account di servizio (roles/iam.serviceAccountTokenCreator) per generare un token ID per l'account di servizio.

gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS  \
  --member user:$ACCOUNT_EMAIL \
  --role='roles/iam.serviceAccountTokenCreator'

Utilizza il token ID dell'account di servizio

Ora puoi richiamare la funzione passando il token ID dell'account di servizio.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)" 

Vedrai quanto segue:

WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com].
Hello World!

6. Scenario 3: utilizzo delle librerie client di Google

Per quest'ultima parte del codelab, eseguirai un servizio di piccole dimensioni in locale per generare un token ID per un account di servizio, quindi chiamerai la funzione in modo programmatico utilizzando le librerie client di Google Auth e le Credenziali predefinite dell'applicazione (ADC). Per ulteriori informazioni sulle librerie client di Google, consulta la sezione dedicata alle librerie client spiegate della documentazione.

L'utilizzo di ADC è particolarmente importante quando vuoi scrivere e testare la tua funzione localmente (ad es. su laptop, in Cloud Shell e così via) durante l'interazione con altre risorse Google Cloud (ad es. Cloud Storage, API Vision e così via). Per questo esempio, vedrai come un servizio richiama un'altra funzione che richiede l'autenticazione. Per ulteriori informazioni su ADC e sullo sviluppo locale, vedi il blog post How to development and test your Cloud Functions localmente | Blog di Google Cloud

Esegui il comando gcloud per impersonare un account di servizio

ADC trova automaticamente le credenziali in base all'ambiente dell'applicazione e le utilizza per eseguire l'autenticazione nelle API Google Cloud. Il flag –impersonate-service-account consente di impersonare un account di servizio utilizzando la sua identità per l'autenticazione contro le API Google Cloud.

Per rappresentare un account di servizio, puoi eseguire questo comando:

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

Ora stai eseguendo i comandi gcloud con quell'account di servizio invece che con la tua identità.

Crea ed esegui un servizio per richiamare una funzione autenticata

Ogni runtime ha la propria libreria client di Google Auth che puoi installare. Questo codelab ti guida nella creazione e nell'esecuzione di un'app Node.js in locale.

Ecco i passaggi per Node.js:

  1. Crea una nuova app Node.js
npm init
  1. Installa la libreria client di Google Auth
npm install google-auth-library
  1. Crea un file index.js
  2. Recupera l'URL della funzione Cloud Functions, che aggiungerai al codice nel passaggio successivo.
echo $FUNCTION_URL
  1. Aggiungi il seguente codice a index.js. Assicurati di modificare la variabile targetAudience nell'URL della funzione Cloud Functions.

index.js

// Cloud Functions uses your function's url as the `targetAudience` value

const targetAudience = '<YOUR-CLOUD-FUNCTION-URL>';

// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal

const url = targetAudience;

const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();

async function request() {
    console.info(`request ${url} with target audience ${targetAudience}`);

    // this call retrieves the ID token for the impersonated service account
    const client = await auth.getIdTokenClient(targetAudience);

    const res = await client.request({ url });
    console.info(res.data);
}

request().catch(err => {
    console.error(err.message);
    process.exitCode = 1;
});
  1. Esegui l'app
node index.js

Dovresti anche vedere il risultato "Hello World!"

Risoluzione dei problemi

Se visualizzi un errore di autorizzazione "iam.serviceAccounts.getOpenIdToken" negato per la risorsa (oppure la risorsa potrebbe non esistere). Attendi qualche minuto per la propagazione del ruolo Creatore token account di servizio.

Se hai ricevuto l'errore Impossibile recuperare il token ID in questo ambiente, utilizza GCE o imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS su un file JSON delle credenziali dell'account di servizio, potresti aver dimenticato di eseguire il comando

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

7. Complimenti!

Complimenti per aver completato il codelab.

Consigliamo di consultare la documentazione su come proteggere Cloud Functions.

Ti consigliamo anche questo blog post sullo sviluppo locale con Cloud Functions per scoprire come sviluppare e testare la funzione Cloud Functions nel tuo ambiente di sviluppo locale.

Argomenti trattati

  • Come configurare l'autenticazione su una funzione Cloud Functions e verificare che l'autenticazione sia stata configurata correttamente
  • Richiama una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
  • Creare un account di servizio e assegnargli il ruolo appropriato per richiamare una funzione
  • Come impersonare un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione

8. Esegui la pulizia

Per evitare addebiti involontari, ad esempio questa funzione Cloud Functions viene richiamata inavvertitamente più volte rispetto all'allocazione mensile dei richiami della funzione Cloud Functions nel livello senza costi, puoi eliminare la funzione Cloud Functions o eliminare il progetto che hai creato nel passaggio 2.

Per interrompere l'identità dell'account di servizio, puoi eseguire nuovamente l'accesso utilizzando la tua identità:

gcloud auth application-default login

Per eliminare la funzione Cloud Functions, vai alla console Cloud Functions all'indirizzo https://console.cloud.google.com/functions/. Assicurati che il progetto che hai creato nel passaggio 2 sia il progetto attualmente selezionato.

Seleziona la funzione my-authenticated-function di cui hai eseguito il deployment in precedenza. Poi tocca Elimina.

Se scegli di eliminare l'intero progetto, puoi andare all'indirizzo https://console.cloud.google.com/cloud-resource-manager, selezionare il progetto che hai creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai modificarli in Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list.