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

1. Wprowadzenie

Omówienie

Funkcje Cloud Run to wymagające niewielu zasobów rozwiązanie oparte na obliczeniach, które umożliwia programistom tworzenie samodzielnych funkcji o ściśle zdefiniowanym przeznaczeniu, które można aktywować za pomocą 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 poście na naszym blogu.

Istnieją 2 główne sposoby kontrolowania wywołań funkcji Cloud Run: zabezpieczanie dostępu na podstawie tożsamości i zabezpieczanie dostępu przy użyciu kontroli dostępu opartej na sieci. To ćwiczenia w Codelabs skupia się na pierwszym podejściu i przedstawia 3 scenariusze zabezpieczania dostępu 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 tworzenia i testowania
  2. Podczas programowania i testowania lokalnie przyjmij tożsamość konta usługi, aby używać tych samych danych logowania co w środowisku produkcyjnym
  3. Używanie bibliotek klienta Google do obsługi uwierzytelniania w interfejsach Google Cloud API, 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 tokenu tożsamości gcloud
  • Jak utworzyć konto usługi i przypisać mu odpowiednią rolę, aby wywołać funkcję
  • Jak podszyć się pod usługę z lokalnego środowiska programistycznego, która ma odpowiednie role do wywołania funkcji

2. Konfiguracja i wymagania

Wymagania wstępne

Aktywowanie Cloud Shell

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

84688aa223b1c3a2.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni, na którym opisano, czym jest to środowisko. Jeśli taki ekran się wyświetlił, kliknij Dalej.

d95252b003979716.png

Uproszczenie i połączenie z Cloud Shell powinno zająć tylko kilka chwil.

7833d5e1c5d18f54.png

Ta maszyna wirtualna zawiera wszystkie niezbędne narzędzia programistyczne. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie poprawia wydajność sieci i uwierzytelnianie. Większość, jeśli nie wszystkie, zadań w tym ćwiczeniu można wykonać w przeglądarce.

Po połączeniu z Cloud Shell powinieneś zobaczyć, że jesteś uwierzytelniony i że projekt jest ustawiony na identyfikator Twojego projektu.

  1. Aby potwierdzić uwierzytelnianie, 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 sprawdzić, czy polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project

Dane wyjściowe polecenia

[core]
project = <PROJECT_ID>

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

gcloud config set project <PROJECT_ID>

Dane wyjściowe polecenia

Updated property [core/project].

3. Tworzenie i testowanie uwierzytelnionej funkcji Cloud Run

Wymaganie uwierzytelniania oznacza, że podmiot wywołujący funkcję musi mieć rolę Wywołujący Cloud Run. W przeciwnym razie funkcja zwróci błąd 403 (Błąd 403: Zabronione). Ten projekt kodu pokazuje, jak przyznać odpowiednie role wywołującego do zasady.

Konfigurowanie lokalnych zmiennych środowiskowych dla uproszczonych poleceń gcloud

Najpierw utwórz kilka zmiennych środowiskowych, aby poprawić czytelność poleceń gcloud używanych w tym ćwiczeniu z programowania.

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

Utwórz kod źródłowy funkcji

Ten moduł Codelab używa Node.js, ale możesz użyć dowolnego środowiska uruchomieniowego 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 uwierzytelnionej funkcji

Aby utworzyć funkcję uwierzytelnioną w środowisku wykonawczym nodejs20, wykonaj te czynności: Możesz jednak użyć dowolnego środowiska uruchomieniowego 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ć jej później.

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

Jeśli wolisz przeprowadzić wdrożenie 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

a potem zapisać URL funkcji jako zmienną środowiskową do późniejszego użycia.

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

Aby sprawdzić, czy funkcja wymaga uwierzytelniania, spróbuj wywołać ją jako anonimowy rozmówca.

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

W wierszu poleceń uruchom to polecenie curl:

curl -i $FUNCTION_URL

Powinien pojawić się taki 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 przejść przez 3 scenariusze, w których można wywołać funkcję przez zapewnienie uwierzytelniania.

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

Jako deweloper potrzebujesz sposobu na testowanie funkcji podczas jej tworzenia lokalnie. W tej sekcji przeprowadzisz szybki test, aby sprawdzić, czy funkcja jest prawidłowo uwierzytelniana za pomocą Twojej tożsamości.

Aby sprawdzić, czy uwierzytelnienie za pomocą usługi gcloud jest aktywne, uruchom to polecenie:

gcloud auth list

Obok aktywnej tożsamości powinien wyświetlać się gwiazdka, na przykład:

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 init i gcloud 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 (Błąd 403 – Zabronione), sprawdź, czy Twoja tożsamość ma rolę Cloud Run Invoker. Aby sprawdzić role przypisane podmiotowi zabezpieczeń, możesz użyć konsoli IAM.

Korzystanie z własnego tokenu tożsamości to szybki sposób na przetestowanie funkcji podczas tworzenia, ale wywołujący uwierzytelnioną funkcję będzie potrzebować odpowiednich ról. W przeciwnym razie otrzyma błąd 403 Brak dostępu.

Warto zastosować zasadę jak najmniejszych uprawnień, ograniczając liczbę tożsamości i kont usługi, które mają role umożliwiające wywołanie funkcji. Z następnego scenariusza dowiesz się, jak utworzyć nowe konto usługi i przypisać do niego odpowiednie role, aby można było wywołać funkcję.

5. Scenariusz 2. Odgrywaj rolę konta usługi

W tym scenariuszu udajesz (czyli przypisujesz sobie uprawnienia) konto usługi, aby wywołać funkcję podczas tworzenia i testowania lokalnie. Udając 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ę minimalnego poziomu uprawnień, ponieważ nie będziesz musiał przypisywać roli wywołującego Cloud Functions innym tożsamościom tylko na potrzeby testów lokalnych.

Na potrzeby tego ćwiczenia w Codelabs utworzysz nowe konto usługi, które ma tylko role do wywoływania funkcji utworzonej w ramach tego ćwiczenia.

Utwórz nowe konto usługi

Najpierw utwórz kilka dodatkowych zmiennych środowiskowych reprezentujących 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"

Przypisz do konta usługi rolę Wywołujący Cloud Run:

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

Wywołaj funkcję przez przyjęcie tożsamości konta usługi

W tym celu będziesz podszywać się pod nowo utworzone konto usługi, uzyskując jego token identyfikacyjny.

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

Aby można było odgrywać rolę konta usługi, konto użytkownika musi mieć rolę Twórca tokenów konta usługi (roles/iam.serviceAccountTokenCreator), co pozwoli na wygenerowanie tokena identyfikatora konta usługi.

Aby przyznać aktywnemu użytkownikowi tę rolę, uruchom 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 identyfikacyjnego konta usługi

Zaczekaj kilka minut na wypełnienie 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:

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 klientów Google

W tej ostatniej części ćwiczenia w Codelabs uruchomisz małą usługę lokalnie, aby wygenerować token identyfikatora dla konta usługi, a następnie automatycznie wywołasz funkcję za pomocą bibliotek klienta Google Auth i domyślnych danych logowania aplikacji (ADC). Więcej informacji o bibliotekach klienta Google znajdziesz w sekcji Biblioteki klienta – wyjaśnienia w dokumentacji.

Korzystanie z ADC jest szczególnie ważne, gdy chcesz napisać i przetestować funkcję lokalnie (np. na laptopie lub w Cloud Shell) podczas interakcji z innymi zasobami Google Cloud (np. Cloud Storage, Vision API itp.). Z tego przykładu dowiesz się, jak usługa wywołuje inną funkcję, która wymaga uwierzytelnienia. Więcej informacji o ADC i programowaniu lokalnym znajdziesz w poście na blogu: Jak lokalnie tworzyć i testować funkcje w Cloud Functions | Blog Google Cloud

Uruchom polecenie gcloud, aby podszyć się pod inne konto usługi

ADC automatycznie wyszukuje dane logowania na podstawie środowiska aplikacji i używa ich do uwierzytelniania w interfejsach Google Cloud APIs. Flaga –impersonate-service-account umożliwia przyjęcie tożsamości konta usługi przez użycie jego tożsamości do uwierzytelniania w odniesieniu do interfejsów API Google Cloud.

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

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

Teraz polecenia gcloud są wykonywane jako to konto usługi, a nie Twoja tożsamość.

Tworzenie i uruchamianie usługi wywołującej uwierzytelnioną funkcję

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

Oto instrukcje dotyczące 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. Utwórz plik 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 widzisz błąd „Uprawnienie 'iam.serviceAccounts.getOpenIdToken' zostało odrzucone” w przypadku zasobu (lub jeśli nie istnieje), odczekaj kilka minut, aż rozpowszechni się rola Twórca tokena konta usługi.

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 do konta usługi, możliwe, że nie uruchomiono polecenia

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

7. Gratulacje!

Gratulujemy ukończenia ćwiczenia.

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

Aby dowiedzieć się, jak opracować i przetestować funkcję Cloud Run w lokalnym środowisku programistycznym, przeczytaj ten wpis na blogu na temat programowania lokalnego z funkcjami Cloud Run.

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 tokenu tożsamości gcloud
  • Jak utworzyć konto usługi i przypisać mu odpowiednią rolę, aby wywołać funkcję
  • Jak podszyć się pod usługę z lokalnego środowiska programistycznego, która ma odpowiednie role do wywołania funkcji

8. Czyszczenie danych

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

Aby przestać podszywać się pod konto usługi, możesz ponownie zalogować się, 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 wybrany jest projekt utworzony w kroku 2.

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

Jeśli chcesz 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. Aby wyświetlić listę wszystkich dostępnych projektów, uruchom gcloud projects list.