Informationen zum Aufrufen authentifizierter Cloud Run-Funktionen

1. Einführung

Übersicht

Cloud Run Functions ist eine einfache Computing-Lösung für Entwickler zum Erstellen zweckgebundener Funktionen, die über HTTPS ausgelöst werden oder auf CloudEvents reagieren können, ohne einen Server oder eine Laufzeitumgebung verwalten zu müssen. Weitere Informationen zu Cloud Run Functions finden Sie in unserem Blogpost.

Es gibt zwei Hauptansätze zum Steuern von Aufrufen von Cloud Run Functions: Zugriff basierend auf der Identität sichern und Zugriff mithilfe von netzwerkbasierten Zugriffssteuerungen sichern. In diesem Codelab geht es um den ersten Ansatz. Wir führen Sie durch drei Szenarien zum Sichern des Zugriffs basierend auf der Identität, um eine Funktion aufzurufen:

  1. Ihr gcloud-Identitätstoken verwenden, um eine Funktion für lokale Entwicklungs- und Testzwecke aufzurufen
  2. Bei der lokalen Entwicklung und beim Testen die Identität eines Dienstkontos übernehmen, um dieselben Anmeldedaten wie in der Produktion zu verwenden
  3. Google-Clientbibliotheken verwenden, um die Authentifizierung bei Google Cloud APIs zu verarbeiten, z.B. wenn ein Dienst eine Funktion aufrufen muss

Lerninhalte

  • Authentifizierung für eine Cloud Run-Funktion konfigurieren und prüfen, ob die Authentifizierung richtig konfiguriert wurde
  • Eine authentifizierte Funktion aus einer lokalen Entwicklungsumgebung aufrufen, indem Sie das Token für Ihre gcloud-Identität angeben
  • Ein Dienstkonto erstellen und ihm die entsprechende Rolle zuweisen, um eine Funktion aufzurufen
  • Die Identität eines Dienstes aus einer lokalen Entwicklungsumgebung übernehmen, der die entsprechenden Rollen zum Aufrufen einer Funktion hat

2. Einrichtung und Anforderungen

Voraussetzungen

  • Sie sind in der Cloud Console angemeldet.
  • Sie haben bereits eine HTTP-getriggerte Cloud Run-Funktion bereitgestellt. Siehe Schnellstartbeispiel.
  • (Optional) Für das dritte Szenario wird in diesem Codelab Node.js und npm als Beispiel verwendet. Sie können aber jede Laufzeit verwenden, die von den Google Auth-Clientbibliotheken unterstützt wird.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren d1264ca30785e435.png.

84688aa223b1c3a2.png

Wenn Sie die Cloud Shell zum ersten Mal starten, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter.

d95252b003979716.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

7833d5e1c5d18f54.png

Diese virtuelle Maschine enthält alle Entwicklungstools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie authentifiziert sind und für das Projekt schon Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Authentifizierte Cloud Run-Funktion erstellen und testen

Wenn eine Authentifizierung erforderlich ist, muss das Hauptkonto, das die Funktion aufruft, die Rolle „Cloud Run-Aufrufer“ haben. Andernfalls gibt die Funktion den Fehler „403 Forbidden“ zurück. In diesem Codelab wird gezeigt, wie Sie einem Hauptkonto die entsprechenden Aufruferrollen zuweisen.

Lokale Umgebungsvariablen für vereinfachte gcloud-Befehle einrichten

Zuerst erstellen Sie einige Umgebungsvariablen, um die Lesbarkeit der gcloud-Befehle in diesem Codelab zu verbessern.

REGION=us-central1
PROJECT_ID=$(gcloud config get-value project)

Quellcode für die Funktion erstellen

In diesem Codelab wird Node.js verwendet. Sie können aber jede Laufzeit verwenden, die von den Google Auth-Clientbibliotheken unterstützt wird.

Erstellen Sie zuerst ein Verzeichnis und wechseln Sie in dieses Verzeichnis.

mkdir auth-function-codelab && cd $_

Erstellen Sie dann die Datei „package.json“.

touch package.json

echo '{
  "dependencies": {
    "@google-cloud/functions-framework": "^3.0.0"
  }
}
' > package.json

Erstellen Sie als Nächstes die Quelldatei „index.js“.

touch index.js

echo 'const functions = require("@google-cloud/functions-framework");

functions.http("helloWorld", (req, res) => {
 res.send(`Hello ${req.query.name || req.body.name || "World"}!`);
});' > index.js

Authentifizierte Funktion erstellen

Hier sind die Schritte zum Erstellen einer authentifizierten Funktion für die Laufzeit „nodejs20“. Sie können aber jede Laufzeit verwenden, die von den Google Auth-Clientbibliotheken unterstützt wird.

FUNCTION_NAME=authenticated-function-codelab
ENTRY_POINT=helloWorld

Führen Sie den folgenden Befehl aus, um eine Cloud Run-Funktion direkt in Cloud Run bereitzustellen:

gcloud beta run deploy $FUNCTION_NAME \
      --source . \
      --function helloWorld \
      --region $REGION \
      --no-allow-unauthenticated

Anschließend können Sie die Funktions-URL als Umgebungsvariable speichern, um sie später zu verwenden.

FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"

Wenn Sie die Bereitstellung als Cloud Functions (2. Generation) bevorzugen, verwenden Sie den folgenden Befehl:

gcloud functions deploy nodejs-http-function \
  --gen2 \
  --runtime=nodejs20 \
  --region=$REGION \
  --source=. \
  --entry-point=helloWorld \
  --trigger-http \
  --no-allow-unauthenticated

Anschließend können Sie die Funktions-URL als Umgebungsvariable speichern, um sie später zu verwenden.

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"

Prüfen, ob für die Funktion eine Authentifizierung erforderlich ist, indem Sie versuchen, sie als anonymer Aufrufer aufzurufen

Sie rufen die Funktion ohne Authentifizierung auf, um zu prüfen, ob Sie den erwarteten Fehler „403“ erhalten.

Führen Sie in der Befehlszeile den folgenden curl-Befehl aus:

curl -i $FUNCTION_URL

Sie sehen das folgende Ergebnis:

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

Jetzt können Sie drei Szenarien durchgehen, in denen Sie Ihre Funktion aufrufen können, indem Sie eine Authentifizierung angeben.

4. Szenario 1: gcloud-Identitätstoken verwenden

Als Entwickler möchten Sie Ihre Funktion testen können, während Sie sie lokal entwickeln. In diesem Abschnitt führen Sie einen kurzen Test durch, um zu prüfen, ob die Funktion mit Ihrer eigenen Identität richtig authentifiziert wird.

Prüfen Sie, ob Sie mit gcloud authentifiziert sind. Führen Sie dazu folgenden Befehl aus:

gcloud auth list

Neben Ihrer aktiven Identität sollte ein Sternchen zu sehen sein, z. B.:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

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

Weitere Informationen zum Einrichten von „gcloud init“ und „gcloud auth login“ finden Sie in der Dokumentation.

Rufen Sie als Nächstes die Funktion auf und übergeben Sie Ihr Identitätstoken.

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

Jetzt sehen Sie das Ergebnis:

Hello World!

Fehlerbehebung

Wenn Sie den Fehler „403 Forbidden“ erhalten, prüfen Sie, ob Ihre Identität die Rolle „Cloud Run-Aufrufer“ hat. In der IAM-Konsole können Sie die Rollen prüfen, die einem Hauptkonto zugewiesen sind.

Die Verwendung Ihres eigenen Identitätstokens ist zwar eine schnelle Möglichkeit, Ihre Funktion während der Entwicklung zu testen, aber der Aufrufer Ihrer authentifizierten Funktion benötigt die entsprechenden Rollen. Andernfalls erhält der Aufrufer den Fehler „403 Forbidden“.

Sie sollten das Prinzip der geringsten Berechtigung befolgen, indem Sie die Anzahl der Identitäten und Dienstkonten begrenzen, die Rollen zum Aufrufen der Funktion haben. Im nächsten Szenario erfahren Sie, wie Sie ein neues Dienstkonto erstellen und ihm die entsprechenden Rollen zuweisen, um die Funktion aufzurufen.

5. Szenario 2: Identität eines Dienstkontos übernehmen

In diesem Szenario übernehmen Sie die Identität eines Dienstkontos (d.h. Sie nehmen die Berechtigungen des Dienstkontos an), um eine Funktion aufzurufen, wenn Sie lokal entwickeln und testen. Wenn Sie die Identität eines Dienstkontos übernehmen, können Sie Ihre Funktion mit denselben Anmeldedaten wie in der Produktion testen.

So können Sie nicht nur Rollen prüfen, sondern auch das Prinzip der geringsten Berechtigung befolgen, da Sie anderen Identitäten die Rolle „Cloud Functions-Aufrufer“ nicht nur für lokale Tests zuweisen müssen.

Für dieses Codelab erstellen Sie ein neues Dienstkonto, das nur Rollen zum Aufrufen der Funktion hat, die Sie in diesem Codelab erstellt haben.

Neues Dienstkonto erstellen

Zuerst erstellen Sie einige zusätzliche Umgebungsvariablen, um die in den gcloud-Befehlen verwendeten Dienstkonten darzustellen.

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

Als Nächstes erstellen Sie das Dienstkonto.

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

Und weisen Sie dem Dienstkonto die Rolle „Cloud Run-Aufrufer“ zu:

gcloud run services add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1  \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/run.invoker'

Funktion aufrufen, indem Sie die Identität des Dienstkontos übernehmen

Dazu übernehmen Sie die Identität des neu erstellten Dienstkontos, indem Sie sein ID-Token abrufen.

Erforderliche Rollen für die Identitätsübernahme hinzufügen

Um die Identität eines Dienstkontos zu übernehmen, muss Ihr Nutzerkonto die Rolle „Ersteller von Dienstkonto-Tokens (roles/iam.serviceAccountTokenCreator)“ haben, um ein ID-Token für das Dienstkonto zu generieren.

Sie können die folgenden Befehle ausführen, um Ihrem aktiven Nutzerkonto diese Rolle zuzuweisen:

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

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

ID-Token des Dienstkontos verwenden

Warten Sie einige Minuten, bis die Berechtigungen übernommen wurden. Jetzt können Sie die Funktion aufrufen, indem Sie das ID-Token des Dienstkontos übergeben.

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

Und Sie sehen Folgendes:

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. Szenario 3: Google-Clientbibliotheken verwenden

Für diesen letzten Teil des Codelabs führen Sie lokal einen kleinen Dienst aus, um ein ID-Token für ein Dienstkonto zu generieren, und rufen dann die Funktion programmatisch mit den Google Auth-Clientbibliotheken und Standardanmeldedaten für Anwendungen (Application Default Credentials, ADC) auf. Weitere Informationen zu Google-Clientbibliotheken finden Sie im Abschnitt Erläuterung zu Clientbibliotheken in der Dokumentation.

Die Verwendung von ADC ist besonders wichtig, wenn Sie Ihre Funktion lokal schreiben und testen möchten (z. B. auf Ihrem Laptop, in der Cloud Shell usw.), während Sie mit anderen Google Cloud-Ressourcen interagieren (z. B. Cloud Storage, Vision API usw.). In diesem Beispiel erfahren Sie, wie ein Dienst eine andere Funktion aufrufen kann, für die eine Authentifizierung erforderlich ist. Weitere Informationen zu ADC und zur lokalen Entwicklung finden Sie im Blogpost How to develop and test your Cloud Functions locally | Google Cloud Blog.

gcloud-Befehl ausführen, um die Identität eines Dienstkontos zu übernehmen

ADC findet Anmeldedaten automatisch basierend auf der Anwendungsumgebung und verwendet diese Anmeldedaten, um sich bei Google Cloud APIs zu authentifizieren. Mit dem Flag „–impersonate-service-account“ können Sie die Identität eines Dienstkontos übernehmen, indem Sie seine Identität für die Authentifizierung bei Google Cloud APIs verwenden.

Führen Sie den folgenden Befehl aus, um die Identität eines Dienstkontos zu übernehmen:

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

Jetzt führen Sie gcloud-Befehle als dieses Dienstkonto und nicht mit Ihrer Identität aus.

Dienst erstellen und ausführen, um eine authentifizierte Funktion aufzurufen

Für jede Laufzeit gibt es eine eigene Google Auth-Clientbibliothek, die Sie installieren können. In diesem Codelab wird beschrieben, wie Sie eine Node.js-Anwendung lokal erstellen und ausführen.

So gehen Sie für Node.js vor:

  1. Neues Verzeichnis erstellen
mkdir local-dev && cd $_
  1. Neue Node.js-Anwendung erstellen
npm init -y
  1. Google Auth-Clientbibliothek installieren
npm install google-auth-library
  1. Datei „index.js“ erstellen
  2. Rufen Sie die URL Ihrer Cloud Run-Funktion ab, die Sie im nächsten Schritt Ihrem Code hinzufügen.
echo $FUNCTION_URL
  1. Fügen Sie der Datei „index.js“ den folgenden Code hinzu. Ändern Sie die Variable „targetAudience“ in die URL Ihrer Cloud Run-Funktion.

index.js

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

const targetAudience = '<YOUR-CLOUD-RUN-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. Anwendung ausführen
node index.js

Sie sollten das Ergebnis „Hello World!“ sehen.

Fehlerbehebung

Wenn der Fehler „Permission ‘iam.serviceAccounts.getOpenIdToken' denied on resource (or it may not exist).“ angezeigt wird, warten Sie einige Minuten, bis die Rolle „Ersteller von Dienstkonto-Tokens“ übernommen wurde.

Wenn Sie den Fehler „Cannot fetch ID token in this environment, use GCE or set the GOOGLE_APPLICATION_CREDENTIALS environment variable to a service account credentials JSON file“ erhalten haben, haben Sie möglicherweise den Befehl

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

7. Glückwunsch!

Sie haben das Codelab abgeschlossen.

Wir empfehlen Ihnen, die Dokumentation zum Sichern von Cloud Run Functions zu lesen.

Wir empfehlen Ihnen auch diesen Blogpost zur lokalen Entwicklung mit Cloud Run Functions, in dem Sie erfahren, wie Sie Ihre Cloud Run-Funktion in Ihrer lokalen Entwicklungsumgebung entwickeln und testen.

Behandelte Themen

  • Authentifizierung für eine Cloud Run-Funktion konfigurieren und prüfen, ob die Authentifizierung richtig konfiguriert wurde
  • Eine authentifizierte Funktion aus einer lokalen Entwicklungsumgebung aufrufen, indem Sie das Token für Ihre gcloud-Identität angeben
  • Ein Dienstkonto erstellen und ihm die entsprechende Rolle zuweisen, um eine Funktion aufzurufen
  • Die Identität eines Dienstes aus einer lokalen Entwicklungsumgebung übernehmen, der die entsprechenden Rollen zum Aufrufen einer Funktion hat

8. Bereinigen

Um unbeabsichtigte Kosten zu vermeiden (z. B. wenn diese Cloud Functions-Funktion versehentlich öfter aufgerufen wird, als Ihre monatliche Zuweisung für Cloud Run-Funktionsaufrufe im kostenlosen Kontingent zulässt), können Sie entweder die Cloud Functions-Funktion oder das in Schritt 2 erstellte Projekt löschen.

Wenn Sie die Identität des Dienstkontos nicht mehr übernehmen möchten, können Sie sich mit Ihrer Identität neu anmelden:

gcloud auth application-default login

Wenn Sie die Cloud Run-Funktion löschen möchten, rufen Sie die Cloud Run-Funktion in der Cloud Console unter https://console.cloud.google.com/functions/ auf. Achten Sie darauf, dass das in Schritt 2 erstellte Projekt als aktuell ausgewähltes Projekt festgelegt ist.

Wählen Sie die zuvor bereitgestellte Funktion my-authenticated-function aus. Klicken Sie dann auf Löschen.

Wenn Sie das gesamte Projekt löschen möchten, rufen Sie https://console.cloud.google.com/cloud-resource-manager auf, wählen Sie das in Schritt 2 erstellte Projekt aus und klicken Sie auf „Löschen“. Wenn Sie das Projekt löschen, müssen Sie die Projekte in Ihrem Cloud SDK ändern. Sie können die Liste aller verfügbaren Projekte mit dem Befehl gcloud projects list aufrufen.