Dowiedz się, jak wywoływać uwierzytelnione funkcje Cloud Run

1. Wprowadzenie

Przegląd

Funkcje Cloud Run to wymagające niewielu zasobów rozwiązanie do przetwarzania danych, które umożliwia programistom tworzenie samodzielnych funkcji o ściśle zdefiniowanym przeznaczeniu, które można wywoływać za pomocą protokołu HTTPS lub które reagują na CloudEvents bez konieczności zarządzania serwerem lub środowiskiem wykonawczym. Więcej informacji o funkcjach Cloud Run znajdziesz w naszym poście na blogu.

Istnieją 2 główne sposoby kontrolowania wywołań funkcji Cloud Run: zabezpieczanie dostępu na podstawie tożsamości i zabezpieczanie dostępu za pomocą kontroli dostępu opartej na sieci. Te ćwiczenia koncentrują się na pierwszym podejściu i przedstawiają 3 scenariusze zabezpieczania dostępu do funkcji na podstawie tożsamości w celu wywołania funkcji:

  1. Używanie tokena tożsamości gcloud do wywoływania funkcji na potrzeby lokalnego programowania i testowania
  2. Przyjmij tożsamość konta usługi podczas programowania i testowania lokalnego, aby używać tych samych danych logowania co w środowisku produkcyjnym.
  3. Używaj bibliotek klienta Google do obsługi uwierzytelniania w Cloud APIs Google, np.gdy usługa musi wywołać funkcję.

Czego się nauczysz

  • Jak skonfigurować uwierzytelnianie w funkcji Cloud Run i sprawdzić, czy zostało ono prawidłowo skonfigurowane
  • Wywoływanie uwierzytelnionej funkcji z lokalnego środowiska programistycznego przez podanie tokena tożsamości gcloud
  • Jak utworzyć konto usługi i przypisać mu odpowiednią rolę do wywoływania funkcji
  • Jak przyjmować tożsamość usługi w lokalnym środowisku programistycznym, które ma odpowiednie role do wywoływania funkcji

2. Konfiguracja i wymagania

Wymagania wstępne

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell d1264ca30785e435.png.

84688aa223b1c3a2.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni z opisem tego środowiska. Jeśli pojawił się ekran pośredni, kliknij Dalej.

d95252b003979716.png

Uzyskanie dostępu do środowiska Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

7833d5e1c5d18f54.png

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Większość zadań w tym ćwiczeniu, a być może wszystkie, możesz wykonać w przeglądarce.

Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu.

  1. Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list

Wynik polecenia

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project

Wynik polecenia

[core]
project = <PROJECT_ID>

Jeśli nie, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Wynik polecenia

Updated property [core/project].

3. Tworzenie i testowanie uwierzytelnionej funkcji Cloud Run

Wymaganie uwierzytelniania oznacza, że podmiot zabezpieczeń wywołujący funkcję musi mieć rolę wywołującego Cloud Run. W przeciwnym razie funkcja zwróci błąd 403 Forbidden. W tym ćwiczeniu dowiesz się, jak przyznać odpowiednie role wywołującego podmiotowi zabezpieczeń.

Konfigurowanie lokalnych zmiennych środowiskowych w celu uproszczenia poleceń gcloud

Najpierw utworzysz kilka zmiennych środowiskowych, aby zwiększyć czytelność poleceń gcloud używanych w tym ćwiczeniu.

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

Tworzenie kodu źródłowego funkcji

W tym ćwiczeniu używamy Node.js, ale możesz użyć dowolnego środowiska wykonawczego obsługiwanego przez biblioteki klienta Google Auth.

Najpierw utwórz katalog i przejdź do niego.

mkdir auth-function-codelab && cd $_

Następnie utwórz plik package.json.

touch package.json

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

Następnie utwórz plik źródłowy 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

Tworzenie funkcji uwierzytelnionej

Poniżej znajdziesz instrukcje tworzenia uwierzytelnionej funkcji w środowisku wykonawczym nodejs20. Możesz jednak używać dowolnego środowiska wykonawczego obsługiwanego przez biblioteki klienta Google Auth.

FUNCTION_NAME=authenticated-function-codelab
ENTRY_POINT=helloWorld

Aby wdrożyć funkcję Cloud Run bezpośrednio w Cloud Run, uruchom to polecenie:

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

Następnie możesz zapisać adres URL funkcji jako zmienną środowiskową, aby użyć go później.

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

Jeśli wolisz wdrożyć funkcję jako Cloud Functions 2 generacji, użyj tego polecenia:

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

Następnie możesz zapisać adres URL funkcji jako zmienną środowiskową, aby użyć go później.

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

Sprawdź, czy funkcja wymaga uwierzytelniania, próbując ją wywołać jako anonimowy rozmówca.

Wywołasz funkcję bez uwierzytelniania, aby sprawdzić, czy otrzymasz oczekiwany błąd 403.

W wierszu poleceń uruchom to polecenie curl:

curl -i $FUNCTION_URL

Wyświetli się ten wynik:

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

Teraz możesz zapoznać się z 3 scenariuszami, w których możesz wywołać funkcję, podając dane uwierzytelniające.

4. Scenariusz 1. Użyj tokena tożsamości gcloud

Jako programista chcesz mieć możliwość testowania funkcji podczas jej tworzenia lokalnie. W tej sekcji przeprowadzisz szybki test, aby sprawdzić, czy funkcja jest prawidłowo uwierzytelniona przy użyciu Twojej tożsamości.

Sprawdź, czy uwierzytelnianie za pomocą gcloud działa prawidłowo, uruchamiając to polecenie:

gcloud auth list

Obok aktywnej tożsamości powinien wyświetlać się znak gwiazdki, np.:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

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

Więcej informacji o konfigurowaniu gcloud initgcloud auth login znajdziesz w dokumentacji.

Następnie wywołaj funkcję i przekaż jej token tożsamości.

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

Teraz zobaczysz wynik:

Hello World!

Rozwiązywanie problemów

Jeśli pojawi się błąd 403 Forbidden, sprawdź, czy Twoja tożsamość ma rolę wywołującego Cloud Run. Aby sprawdzić role przypisane do podmiotu zabezpieczeń, możesz użyć konsoli IAM.

Używanie własnego tokena tożsamości to szybki sposób na testowanie funkcji podczas programowania, ale osoba wywołująca uwierzytelnioną funkcję musi mieć odpowiednie role. W przeciwnym razie otrzyma błąd 403 Forbidden.

Zgodnie z zasadą jak najmniejszych uprawnień ogranicz liczbę tożsamości i kont usług, które mają role umożliwiające wywoływanie funkcji. W następnym scenariuszu dowiesz się, jak utworzyć nowe konto usługi i przyznać mu odpowiednie role do wywoływania funkcji.

5. Scenariusz 2. Przyjmowanie tożsamości konta usługi

W tym scenariuszu będziesz przyjmować tożsamość (czyli przyjmować uprawnienia) konta usługi, aby wywoływać funkcję podczas programowania i testowania lokalnego. Dzięki podszywaniu się pod konto usługi możesz testować funkcję przy użyciu tych samych danych logowania co w środowisku produkcyjnym.

Dzięki temu nie tylko zweryfikujesz role, ale też zastosujesz zasadę jak najmniejszych uprawnień, ponieważ nie musisz przyznawać roli wywołującego Cloud Functions innym tożsamościom tylko na potrzeby testowania lokalnego.

Na potrzeby tego ćwiczenia utworzysz nowe konto usługi, które będzie miało tylko role umożliwiające wywoływanie funkcji utworzonej w tym ćwiczeniu.

Utwórz nowe konto usługi

Najpierw utworzysz kilka dodatkowych zmiennych środowiskowych, które będą reprezentować konta usługi używane w poleceniach gcloud.

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

Następnie utwórz konto usługi.

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

Następnie przypisz do konta usługi rolę wywołującego Cloud Run:

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

Wywoływanie funkcji przez podawanie się za konto usługi

W tym celu przyjmiesz tożsamość nowo utworzonego konta usługi, uzyskując jego token tożsamości.

Dodawanie wymaganych ról do przyjmowania tożsamości

Aby podszywać się pod konto usługi, Twoje konto użytkownika musi mieć rolę Twórca tokenów kont usługi (roles/iam.serviceAccountTokenCreator), która umożliwia generowanie tokena tożsamości dla konta usługi.

Aby przyznać tę rolę aktywnemu kontu użytkownika, możesz uruchomić te polecenia:

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'

Używanie tokena tożsamości konta usługi

Zaczekaj kilka minut na rozpowszechnienie uprawnień. Teraz możesz wywołać funkcję, przekazując token identyfikatora konta usługi.

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

Zobaczysz te informacje:

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. Scenariusz 3. Korzystanie z bibliotek klienta Google

W ostatniej części tego ćwiczenia uruchomisz małą usługę lokalnie, aby wygenerować token identyfikatora dla konta usługi, a następnie programowo wywołać funkcję za pomocą bibliotek klienta Google Authdomyślnego uwierzytelniania aplikacji (ADC). Więcej informacji o bibliotekach klienta Google znajdziesz w sekcji wyjaśniającej biblioteki klienta w dokumentacji.

Korzystanie z ADC jest szczególnie ważne, gdy chcesz pisać i testować funkcję lokalnie (np. na laptopie, w Cloud Shell itp.) podczas interakcji z innymi zasobami Google Cloud (np. Cloud Storage, Vision API itp.). W tym przykładzie dowiesz się, jak sprawić, aby usługa wywoływała inną funkcję, która wymaga uwierzytelniania. Więcej informacji o ADC i lokalnym programowaniu znajdziesz w poście na blogu How to develop and test your Cloud Functions locally | Google Cloud Blog (Jak programować i testować funkcje Cloud Functions lokalnie | Blog Google Cloud).

Uruchamianie polecenia gcloud w celu przyjęcia tożsamości konta usługi

ADC automatycznie znajduje dane logowania na podstawie środowiska aplikacji i używa ich do uwierzytelniania w interfejsach Google Cloud APIs. Flaga –impersonate-service-account umożliwia przyjmowanie tożsamości konta usługi przez używanie jego tożsamości do uwierzytelniania w interfejsach Google Cloud APIs.

Aby przyjąć tożsamość konta usługi, możesz uruchomić to polecenie:

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

Polecenia gcloud są teraz uruchamiane jako to konto usługi, a nie jako Twoja tożsamość.

Tworzenie i uruchamianie usługi do wywoływania uwierzytelnionej funkcji

Każde środowisko wykonawcze ma własną bibliotekę klienta Google Auth, którą możesz zainstalować. W tym ćwiczeniu dowiesz się, jak utworzyć i uruchomić lokalnie aplikację Node.js.

Oto instrukcje dla Node.js:

  1. Tworzenie nowego katalogu
mkdir local-dev && cd $_
  1. Tworzenie nowej aplikacji Node.js
npm init -y
  1. Instalowanie biblioteki klienta Google Auth
npm install google-auth-library
  1. Tworzenie pliku index.js
  2. Pobierz adres URL funkcji Cloud Run, który dodasz do kodu w następnym kroku.
echo $FUNCTION_URL
  1. Dodaj ten kod do pliku index.js. Pamiętaj, aby zmienić zmienną targetAudience na adres URL funkcji Cloud Run.

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. Uruchamianie aplikacji
node index.js

Powinien wyświetlić się komunikat „Hello World!”.

Rozwiązywanie problemów

Jeśli pojawi się błąd „Permission ‘iam.serviceAccounts.getOpenIdToken' denied on resource (or it may not exist)” (Odmowa dostępu do zasobu (lub zasób może nie istnieć) z powodu uprawnienia „iam.serviceAccounts.getOpenIdToken”), poczekaj kilka minut, aż rola Twórca tokenów konta usługi zostanie rozpowszechniona.

Jeśli pojawi się błąd Nie można pobrać tokena identyfikatora w tym środowisku, użyj GCE lub ustaw zmienną środowiskową GOOGLE_APPLICATION_CREDENTIALS na plik JSON z danymi logowania konta usługi, być może zapomniałeś(-aś) uruchomić polecenie

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

7. Gratulacje!

Gratulujemy ukończenia ćwiczenia!

Zalecamy zapoznanie się z dokumentacją dotyczącą zabezpieczania funkcji Cloud Run.

Polecamy też ten post na blogu o lokalnym programowaniu funkcji Cloud Run, w którym dowiesz się, jak tworzyć i testować funkcje Cloud Run w lokalnym środowisku programistycznym.

Omówione zagadnienia

  • Jak skonfigurować uwierzytelnianie w funkcji Cloud Run i sprawdzić, czy zostało ono prawidłowo skonfigurowane
  • Wywoływanie uwierzytelnionej funkcji z lokalnego środowiska programistycznego przez podanie tokena tożsamości gcloud
  • Jak utworzyć konto usługi i przypisać mu odpowiednią rolę do wywoływania funkcji
  • Jak przyjmować tożsamość usługi w lokalnym środowisku programistycznym, które ma odpowiednie role do wywoływania funkcji

8. Czyszczenie danych

Aby uniknąć przypadkowych opłat (np. gdy ta funkcja Cloud Functions zostanie przypadkowo wywołana więcej razy niż miesięczny limit wywołań funkcji Cloud Run w warstwie bezpłatnej), możesz usunąć funkcję Cloud Functions lub projekt utworzony w kroku 2.

Aby przestać podszywać się pod konto usługi, możesz zalogować się ponownie, używając swojej tożsamości:

gcloud auth application-default login

Aby usunąć funkcję Cloud Run, otwórz konsolę Cloud Run pod adresem https://console.cloud.google.com/functions/. Upewnij się, że projekt utworzony w kroku 2 jest obecnie wybranym projektem.

Wybierz wdrożoną wcześniej funkcję my-authenticated-function. Następnie kliknij Usuń.

Jeśli zdecydujesz się usunąć cały projekt, otwórz stronę https://console.cloud.google.com/cloud-resource-manager, wybierz projekt utworzony w kroku 2 i kliknij Usuń. Jeśli usuniesz projekt, musisz zmienić projekty w Cloud SDK. Listę wszystkich dostępnych projektów możesz wyświetlić, uruchamiając polecenie gcloud projects list.