Programmatische Authentifizierung

Auf dieser Seite wird beschrieben, wie Sie sich über ein Nutzerkonto oder ein Dienstkonto bei einer mit Identity-Aware Proxy (IAP) gesicherten Ressource authentifizieren.

Beim programmatischen Zugriff rufen Sie IAP-geschützte Anwendungen von Nicht-Browser-Clients auf. Dazu gehören Befehlszeilentools, Dienst-zu-Dienst-Aufrufe und mobile Anwendungen. Je nach Anwendungsfall möchten Sie sich möglicherweise mit Nutzeranmeldedaten oder Dienstkontoanmeldedaten bei IAP authentifizieren.

  • Ein Nutzerkonto gehört zu einem einzelnen Nutzer. Ein Nutzerkonto muss authentifiziert werden, wenn Ihre Anwendung im Namen eines Nutzers auf Ressourcen zugreifen soll, die mit IAP gesichert sind. Weitere Informationen finden Sie unter Nutzerkonten.

  • Ein Dienstkonto repräsentiert eine Anwendung und keinen einzelnen Nutzer. Ein Dienstkonto muss authentifiziert werden, wenn Sie einer Anwendung Zugriff auf Ihre mit IAP gesicherten Ressourcen gewähren möchten. Weitere Informationen finden Sie unter Dienstkonten.

IAP unterstützt die folgenden Arten von Anmeldedaten für den programmatischen Zugriff:

  • OAuth 2.0-ID-Token: Ein von Google ausgestelltes Token für einen menschlichen Nutzer oder ein Dienstkonto, bei dem der Zielgruppenanspruch auf die Ressourcen-ID der IAP-Anwendung festgelegt ist.
  • Vom Dienstkonto signiertes JWT: Ein selbstsigniertes oder von Google ausgestelltes JWT-Token für ein Dienstkonto.

Übergeben Sie diese Anmeldedaten an IAP im HTTP-Header Authorization oder Proxy-Authorization.

Hinweise

Bevor Sie beginnen, benötigen Sie eine mit IAP gesicherte Anwendung, zu der Sie mithilfe der Anmeldedaten eines Entwicklerkontos, eines Dienstkontos oder einer mobilen App programmatisch eine Verbindung herstellen möchten.

Nutzerkonto authentifizieren

Damit ein Programm mit einer Ressource interagieren kann, die mit IAP gesichert ist, können Sie den Nutzerzugriff von einer Desktopanwendung oder einer mobilen App auf Ihre Anwendung aktivieren.

Von einer mobilen App aus authentifizieren

  1. Erstellen Sie eine OAuth 2.0-Client-ID für Ihre mobile App oder verwenden Sie eine vorhandene. Wenn Sie eine vorhandene OAuth 2.0-Client-ID verwenden möchten, folgen Sie der Anleitung unter OAuth-Clients freigeben. Fügen Sie die OAuth-Client-ID der Zulassungsliste für den programmatischen Zugriff für die Anwendung hinzu.
  2. Rufen Sie ein ID-Token für die mit IAP gesicherte Client-ID ab.
  3. Fügen Sie das ID-Token in einen Authorization: Bearer-Header ein, um die authentifizierte Anfrage an die mit IAP gesicherte Ressource zu senden.

Von einer Desktopanwendung aus authentifizieren

In diesem Abschnitt wird beschrieben, wie Sie ein Nutzerkonto von einer Desktop-Befehlszeile aus authentifizieren können.

  1. Damit Entwickler über die Befehlszeile auf Ihre Anwendung zugreifen können, müssen Sie eine OAuth 2.0-Client-ID für Desktop-Apps erstellen oder eine vorhandene OAuth-Client-ID für Desktop-Apps freigeben.
  2. Fügen Sie die OAuth-ID der Zulassungsliste für programmatischen Zugriff für die Anwendung hinzu.

In der App anmelden

Jeder Entwickler, der auf eine mit IAP gesicherte App zugreifen möchte, muss sich als Erstes anmelden. Sie können den Vorgang in einem Skript bündeln, z. B. mit der gcloud CLI. Im folgenden Beispiel wird curl verwendet, um sich anzumelden und ein Token zu generieren, mit dem auf die Anwendung zugegriffen werden kann:

  1. Melden Sie sich in Ihrem Konto an, das Zugriff auf die Google Cloud -Ressource hat.
  2. Starten Sie einen lokalen Server, der die eingehenden Anfragen wiederholen kann.

      # Example using Netcat (http://netcat.sourceforge.net/)
      nc -k -l 4444
    
  3. Rufen Sie den folgenden URI auf, wobei DESKTOP_CLIENT_ID die Client-ID der Desktop-App ist:

      https://accounts.google.com/o/oauth2/v2/auth?client_id=DESKTOP_CLIENT_ID&response_type=code&scope=openid%20email&access_type=offline&redirect_uri=http://localhost:4444&cred_ref=true
    
  4. Suchen Sie in der Ausgabe des lokalen Servers nach den Anfrageparametern:

      GET /?code=CODE&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email&hd=google.com&prompt=consent HTTP/1.1
    
  5. Kopieren Sie den CODE-Wert, um AUTH_CODE im folgenden Befehl zu ersetzen, zusammen mit der Client-ID und dem Secret der Desktop-App:

      curl --verbose \
        --data client_id=DESKTOP_CLIENT_ID \
        --data client_secret=DESKTOP_CLIENT_SECRET \
        --data code=CODE \
        --data redirect_uri=http://localhost:4444 \
        --data grant_type=authorization_code \
        https://oauth2.googleapis.com/token
    

    Dieser Befehl gibt ein JSON-Objekt mit dem Feld id_token zurück, mit dem Sie auf die Anwendung zugreifen können.

Auf die Anwendung zugreifen

Für den Zugriff auf die App verwenden Sie id_token:

curl --verbose --header 'Authorization: Bearer ID_TOKEN' URL

Aktualisierungstoken

Mit dem beim Anmelden generierten Aktualisierungstoken können Sie neue ID-Tokens abrufen. Das ist nützlich, wenn das ursprüngliche ID-Token abläuft. Jedes ID-Token ist etwa eine Stunde lang gültig. In dieser Zeit können Sie mehrere Anfragen an eine bestimmte App senden.

Im folgenden Beispiel wird mit curl ein neues ID-Token mit dem Aktualisierungstoken abgerufen. In diesem Beispiel ist REFRESH_TOKEN das Token aus dem Anmeldevorgang. DESKTOP_CLIENT_ID und DESKTOP_CLIENT_SECRET sind dieselben wie im Anmeldevorgang:

curl --verbose \
  --data client_id=DESKTOP_CLIENT_ID \
  --data client_secret=DESKTOP_CLIENT_SECRET \
  --data refresh_token=REFRESH_TOKEN \
  --data grant_type=refresh_token \
  https://oauth2.googleapis.com/token

Dieser Befehl gibt ein JSON-Objekt mit einem neuen id_token-Feld zurück, mit dem Sie auf die App zugreifen können.

Dienstkonto authentifizieren

Sie können ein Dienstkonto-JWT oder ein OpenID Connect-Token (OIDC) verwenden, um ein Dienstkonto bei einer mit IAP gesicherten Ressource zu authentifizieren. In der folgenden Tabelle sind einige der Unterschiede zwischen den verschiedenen Authentifizierungstokens und ihren Funktionen aufgeführt.

Authentifizierungsfunktionen Dienstkonto-JWT OpenID Connect-Token
Unterstützung für den kontextsensitiven Zugriff
Anforderung für OAuth 2.0-Client-ID
Tokenbereich URL der IAP-gesicherten Ressource OAuth 2.0-Client-ID

Mit einem Dienstkonto-JWT authentifizieren

IAP unterstützt die JWT-Authentifizierung von Dienstkonten für Google-Identitäten, Identity Platform und für Anwendungen, die für die Mitarbeiteridentitätsföderation konfiguriert sind.

Die Authentifizierung eines Dienstkontos mit einem JWT umfasst die folgenden Hauptschritte:

  1. Weisen Sie dem aufrufenden Dienstkonto die Rolle Ersteller von Dienstkonto-Tokens (roles/iam.serviceAccountTokenCreator) zu.

    Mit dieser Rolle können Hauptkonten kurzlebige Anmeldedaten wie JWTs erstellen.

  2. Erstellen Sie ein JWT für die mit IAP gesicherte Ressource.

  3. Signieren Sie das JWT mit dem privaten Schlüssel des Dienstkontos.

JWT erstellen

Das erstellte JWT sollte eine Nutzlast haben, die dem folgenden Beispiel ähnelt:

{
  "iss": SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "sub": SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "aud": TARGET_URL,
  "iat": IAT,
  "exp": EXP,
}
  • Geben Sie für die Felder iss und sub die E-Mail-Adresse des Dienstkontos an. Sie finden sie im Feld client_email der JSON-Datei des Dienstkontos oder sie wird übergeben. Typisches Format: service-account@PROJECT_ID.iam.gserviceaccount.com

  • Geben Sie für das Feld aud die URL der IAP-geschützten Ressource an.

  • Geben Sie für das Feld iat die aktuelle Unix-Epochenzeit und für das Feld exp eine Zeit innerhalb von 3.600 Sekunden später an. Hier wird festgelegt, wann das JWT abläuft.

JWT signieren

Sie haben folgende Möglichkeiten, das JWT zu signieren:

  • Mit der IAM Credentials API können Sie ein JWT signieren, ohne direkten Zugriff auf einen privaten Schlüssel zu benötigen.
  • Verwenden Sie eine lokale Schlüsseldatei für Anmeldedaten, um das JWT lokal zu signieren.
JWT mit der IAM Service Account Credentials API signieren

Verwenden Sie die IAM Service Account Credentials API, um ein Dienstkonto-JWT zu signieren. Mit der Methode wird der private Schlüssel abgerufen, der Ihrem Dienstkonto zugeordnet ist, und zum Signieren der JWT-Nutzlast verwendet. Dadurch kann ein JWT signiert werden, ohne dass ein direkter Zugriff auf einen privaten Schlüssel erforderlich ist.

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

gcloud

  1. Führen Sie den folgenden Befehl aus, um eine Anfrage mit der JWT-Nutzlast vorzubereiten.
cat > claim.json << EOM
{
  "iss": "SERVICE_ACCOUNT_EMAIL_ADDRESS",
  "sub": "SERVICE_ACCOUNT_EMAIL_ADDRESS",
  "aud": "TARGET_URL",
  "iat": $(date +%s),
  "exp": $((`date +%s` + 3600))
}
EOM
  1. Verwenden Sie den folgenden Google Cloud CLI-Befehl, um die Nutzlast in claim.json zu signieren:
gcloud iam service-accounts sign-jwt --iam-account="SERVICE_ACCOUNT_EMAIL_ADDRESS" claim.json output.jwt

Nach einer erfolgreichen Anfrage enthält output.jwt ein signiertes JWT, mit dem Sie auf Ihre mit IAP gesicherte Ressource zugreifen können.

Python

import datetime
import json

import google.auth
from google.cloud import iam_credentials_v1

def generate_jwt_payload(service_account_email: str, resource_url: str) -> str:
    """Generates JWT payload for service account.

    Creates a properly formatted JWT payload with standard claims (iss, sub, aud,
    iat, exp) needed for IAP authentication.

    Args:
        service_account_email (str): Specifies service account JWT is created for.
        resource_url (str): Specifies scope of the JWT, the URL that the JWT will
            be allowed to access.

    Returns:
        str: JSON string containing the JWT payload with properly formatted claims.
    """
    # Create current time and expiration time (1 hour later) in UTC
    iat = datetime.datetime.now(tz=datetime.timezone.utc)
    exp = iat + datetime.timedelta(seconds=3600)

    # Convert datetime objects to numeric timestamps (seconds since epoch)
    # as required by JWT standard (RFC 7519)
    payload = {
        "iss": service_account_email,
        "sub": service_account_email,
        "aud": resource_url,
        "iat": int(iat.timestamp()),
        "exp": int(exp.timestamp()),
    }

    return json.dumps(payload)

def sign_jwt(target_sa: str, resource_url: str) -> str:
    """Signs JWT payload using ADC and IAM credentials API.

    Uses Google Cloud's IAM Credentials API to sign a JWT. This requires the
    caller to have iap.webServiceVersions.accessViaIap permission on the target
    service account.

    Args:
        target_sa (str): Service Account JWT is being created for.
            iap.webServiceVersions.accessViaIap permission is required.
        resource_url (str): Audience of the JWT, and scope of the JWT token.
            This is the url of the IAP protected application.

    Returns:
        str: A signed JWT that can be used to access IAP protected apps.
            Use in Authorization header as: 'Bearer <signed_jwt>'
    """
    # Get default credentials from environment or application credentials
    source_credentials, project_id = google.auth.default()

    # Initialize IAM credentials client with source credentials
    iam_client = iam_credentials_v1.IAMCredentialsClient(credentials=source_credentials)

    # Generate the service account resource name
    # If project_id is None, use '-' as placeholder as per API requirements
    project = project_id if project_id else "-"
    name = iam_client.service_account_path(project, target_sa)

    # Create and sign the JWT payload
    payload = generate_jwt_payload(target_sa, resource_url)

    # Sign the JWT using the IAM credentials API
    response = iam_client.sign_jwt(name=name, payload=payload)

    return response.signed_jwt

curl

  1. Führen Sie den folgenden Befehl aus, um eine Anfrage mit der JWT-Nutzlast vorzubereiten:

    cat << EOF > request.json
    {
      "payload": JWT_PAYLOAD
    }
    EOF
    
  2. JWT mit IAM signieren

    Service Account Credentials API:

    curl -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
      -d @request.json \
      "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL_ADDRESS:signJwt"
    

    Nach einer erfolgreichen Anfrage wird in der Antwort ein signiertes JWT zurückgegeben.

  3. Verwenden Sie das JWT, um auf Ihre mit IAP gesicherte Ressource zuzugreifen.

JWT mit einer lokalen Anmeldedaten-Schlüsseldatei signieren

JWTs werden mit dem privaten Schlüssel des Dienstkontos signiert.

Wenn Sie eine Schlüsseldatei für das Dienstkonto haben, kann das JWT lokal signiert werden.

Das Skript sendet einen JWT-Header zusammen mit der Nutzlast. Verwenden Sie für das Feld kid im Header die ID des privaten Schlüssels des Dienstkontos, die sich im Feld private_key_id der JSON-Datei mit den Anmeldedaten des Dienstkontos befindet. Der Schlüssel wird auch zum Signieren des JWT verwendet.

Auf die Anwendung zugreifen

In allen Fällen verwenden Sie für den Zugriff auf die App signed-jwt:

curl --verbose --header 'Authorization: Bearer SIGNED_JWT' URL

Mit einem OIDC-Token authentifizieren

  1. Erstellen Sie eine OAuth 2.0-Client-ID oder verwenden Sie eine vorhandene. Wenn Sie eine vorhandene OAuth 2.0-Client-ID verwenden möchten, folgen Sie der Anleitung unter OAuth-Clients freigeben.
  2. Fügen Sie die OAuth-ID der Zulassungsliste für programmatischen Zugriff für die Anwendung hinzu.
  3. Achten Sie darauf, dass das Standarddienstkonto der Zugriffsliste für das mit IAP gesicherte Projekt hinzugefügt wird.

Wenn Sie Anfragen an die mit IAP gesicherte Ressource senden, müssen Sie das Token in den Authorization-Header einfügen: Authorization: 'Bearer OIDC_TOKEN'

Die folgenden Codebeispiele zeigen, wie Sie ein OIDC-Token erhalten.

OIDC-Token für das Standarddienstkonto abrufen

Wenn Sie ein OIDC-Token für das Standarddienstkonto für Compute Engine, App Engine oder Cloud Run abrufen möchten, können Sie das folgende Codebeispiel verwenden, um das Token zu generieren, um auf eine mit IAP gesicherte Ressource zuzugreifen:

C#

Richten Sie zur Authentifizierung bei IAP Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


using Google.Apis.Auth.OAuth2;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

public class IAPClient
{
    /// <summary>
    /// Makes a request to a IAP secured application by first obtaining
    /// an OIDC token.
    /// </summary>
    /// <param name="iapClientId">The client ID observed on 
    /// https://console.cloud.google.com/apis/credentials. </param>
    /// <param name="uri">HTTP URI to fetch.</param>
    /// <param name="cancellationToken">The token to propagate operation cancel notifications.</param>
    /// <returns>The HTTP response message.</returns>
    public async Task<HttpResponseMessage> InvokeRequestAsync(
        string iapClientId, string uri, CancellationToken cancellationToken = default)
    {
        // Get the OidcToken.
        // You only need to do this once in your application
        // as long as you can keep a reference to the returned OidcToken.
        OidcToken oidcToken = await GetOidcTokenAsync(iapClientId, cancellationToken);

        // Before making an HTTP request, always obtain the string token from the OIDC token,
        // the OIDC token will refresh the string token if it expires.
        string token = await oidcToken.GetAccessTokenAsync(cancellationToken);

        // Include the OIDC token in an Authorization: Bearer header to 
        // IAP-secured resource
        // Note: Normally you would use an HttpClientFactory to build the httpClient.
        // For simplicity we are building the HttpClient directly.
        using HttpClient httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        return await httpClient.GetAsync(uri, cancellationToken);
    }

    /// <summary>
    /// Obtains an OIDC token for authentication an IAP request.
    /// </summary>
    /// <param name="iapClientId">The client ID observed on 
    /// https://console.cloud.google.com/apis/credentials. </param>
    /// <param name="cancellationToken">The token to propagate operation cancel notifications.</param>
    /// <returns>The HTTP response message.</returns>
    public async Task<OidcToken> GetOidcTokenAsync(string iapClientId, CancellationToken cancellationToken)
    {
        // Obtain the application default credentials.
        GoogleCredential credential = await GoogleCredential.GetApplicationDefaultAsync(cancellationToken);

        // Request an OIDC token for the Cloud IAP-secured client ID.
       return await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(iapClientId), cancellationToken);
    }
}

Go

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

import (
	"context"
	"fmt"
	"io"
	"net/http"

	"google.golang.org/api/idtoken"
)

// makeIAPRequest makes a request to an application protected by Identity-Aware
// Proxy with the given audience.
func makeIAPRequest(w io.Writer, request *http.Request, audience string) error {
	// request, err := http.NewRequest("GET", "http://example.com", nil)
	// audience := "IAP_CLIENT_ID.apps.googleusercontent.com"
	ctx := context.Background()

	// client is a http.Client that automatically adds an "Authorization" header
	// to any requests made.
	client, err := idtoken.NewClient(ctx, audience)
	if err != nil {
		return fmt.Errorf("idtoken.NewClient: %w", err)
	}

	response, err := client.Do(request)
	if err != nil {
		return fmt.Errorf("client.Do: %w", err)
	}
	defer response.Body.Close()
	if _, err := io.Copy(w, response.Body); err != nil {
		return fmt.Errorf("io.Copy: %w", err)
	}

	return nil
}

Java

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.IdTokenCredentials;
import com.google.auth.oauth2.IdTokenProvider;
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.util.Collections;

public class BuildIapRequest {
  private static final String IAM_SCOPE = "https://www.googleapis.com/auth/iam";

  private static final HttpTransport httpTransport = new NetHttpTransport();

  private BuildIapRequest() {}

  private static IdTokenProvider getIdTokenProvider() throws IOException {
    GoogleCredentials credentials =
        GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(IAM_SCOPE));

    Preconditions.checkNotNull(credentials, "Expected to load credentials");
    Preconditions.checkState(
        credentials instanceof IdTokenProvider,
        String.format(
            "Expected credentials that can provide id tokens, got %s instead",
            credentials.getClass().getName()));

    return (IdTokenProvider) credentials;
  }

  /**
   * Clone request and add an IAP Bearer Authorization header with ID Token.
   *
   * @param request Request to add authorization header
   * @param iapClientId OAuth 2.0 client ID for IAP protected resource
   * @return Clone of request with Bearer style authorization header with ID Token.
   * @throws IOException exception creating ID Token
   */
  public static HttpRequest buildIapRequest(HttpRequest request, String iapClientId)
      throws IOException {

    IdTokenProvider idTokenProvider = getIdTokenProvider();
    IdTokenCredentials credentials =
        IdTokenCredentials.newBuilder()
            .setIdTokenProvider(idTokenProvider)
            .setTargetAudience(iapClientId)
            .build();

    HttpRequestInitializer httpRequestInitializer = new HttpCredentialsAdapter(credentials);

    return httpTransport
        .createRequestFactory(httpRequestInitializer)
        .buildRequest(request.getRequestMethod(), request.getUrl(), request.getContent());
  }
}

Node.js

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const url = 'https://some.iap.url';
// const targetAudience = 'IAP_CLIENT_ID.apps.googleusercontent.com';

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

async function request() {
  console.info(`request IAP ${url} with target audience ${targetAudience}`);
  const client = await auth.getIdTokenClient(targetAudience);
  const res = await client.fetch(url);
  console.info(res.data);
}

request().catch(err => {
  console.error(err.message);
  process.exitCode = 1;
});

PHP

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

namespace Google\Cloud\Samples\Iap;

# Imports Auth libraries and Guzzle HTTP libraries.
use Google\Auth\ApplicationDefaultCredentials;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;

/**
 * Make a request to an application protected by Identity-Aware Proxy.
 *
 * @param string $url The Identity-Aware Proxy-protected URL to fetch.
 * @param string $clientId The client ID used by Identity-Aware Proxy.
 */
function make_iap_request($url, $clientId)
{
    // create middleware, using the client ID as the target audience for IAP
    $middleware = ApplicationDefaultCredentials::getIdTokenMiddleware($clientId);
    $stack = HandlerStack::create();
    $stack->push($middleware);

    // create the HTTP client
    $client = new Client([
        'handler' => $stack,
        'auth' => 'google_auth'
    ]);

    // make the request
    $response = $client->get($url);
    print('Printing out response body:');
    print($response->getBody());
}

Python

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests


def make_iap_request(url, client_id, method="GET", **kwargs):
    """Makes a request to an application protected by Identity-Aware Proxy.

    Args:
      url: The Identity-Aware Proxy-protected URL to fetch.
      client_id: The client ID used by Identity-Aware Proxy.
      method: The request method to use
              ('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
      **kwargs: Any of the parameters defined for the request function:
                https://github.com/requests/requests/blob/master/requests/api.py
                If no timeout is provided, it is set to 90 by default.

    Returns:
      The page body, or raises an exception if the page couldn't be retrieved.
    """
    # Set the default timeout, if missing
    if "timeout" not in kwargs:
        kwargs["timeout"] = 90

    # Obtain an OpenID Connect (OIDC) token from metadata server or using service
    # account.
    open_id_connect_token = id_token.fetch_id_token(Request(), client_id)

    # Fetch the Identity-Aware Proxy-protected URL, including an
    # Authorization header containing "Bearer " followed by a
    # Google-issued OpenID Connect token for the service account.
    resp = requests.request(
        method,
        url,
        headers={"Authorization": "Bearer {}".format(open_id_connect_token)},
        **kwargs
    )
    if resp.status_code == 403:
        raise Exception(
            "Service account does not have permission to "
            "access the IAP-protected application."
        )
    elif resp.status_code != 200:
        raise Exception(
            "Bad response from application: {!r} / {!r} / {!r}".format(
                resp.status_code, resp.headers, resp.text
            )
        )
    else:
        return resp.text

Ruby

Richten Sie zur Authentifizierung bei IAP die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

# url = "The Identity-Aware Proxy-protected URL to fetch"
# client_id = "The client ID used by Identity-Aware Proxy"
require "googleauth"
require "faraday"

# The client ID as the target audience for IAP
id_token_creds = Google::Auth::Credentials.default target_audience: client_id

headers = {}
id_token_creds.client.apply! headers

resp = Faraday.get url, nil, headers

if resp.status == 200
  puts "X-Goog-Iap-Jwt-Assertion:"
  puts resp.body
else
  puts "Error requesting IAP"
  puts resp.status
  puts resp.headers
end

OIDC-Token aus einer lokalen Dienstkonto-Schlüsseldatei abrufen

Wenn Sie ein OIDC-Token mit einer Dienstkontoschlüsseldatei generieren möchten, verwenden Sie die Schlüsseldatei, um eine JWT-Assertion zu erstellen und zu signieren. Anschließend tauschen Sie diese Assertion gegen ein ID-Token ein. Das folgende Bash-Skript veranschaulicht diesen Vorgang:

Bash

#!/usr/bin/env bash
#
# Example script that generates an OIDC token using a service account key file
# and uses it to access an IAP-secured resource

set -euo pipefail

get_token() {
  # Get the bearer token in exchange for the service account credentials
  local service_account_key_file_path="${1}"
  local iap_client_id="${2}"

  # Define the scope and token endpoint
  local iam_scope="https://www.googleapis.com/auth/iam"
  local oauth_token_uri="https://www.googleapis.com/oauth2/v4/token"

  # Extract data from service account key file
  local private_key_id="$(cat "${service_account_key_file_path}" | jq -r '.private_key_id')"
  local client_email="$(cat "${service_account_key_file_path}" | jq -r '.client_email')"
  local private_key="$(cat "${service_account_key_file_path}" | jq -r '.private_key')"

  # Set token timestamps (current time and expiration 10 minutes later)
  local issued_at="$(date +%s)"
  local expires_at="$((issued_at + 600))"

  # Create JWT header and payload
  local header="{'alg':'RS256','typ':'JWT','kid':'${private_key_id}'}"
  local header_base64="$(echo "${header}" | base64 | tr -d '\n')"
  local payload="{'iss':'${client_email}','aud':'${oauth_token_uri}','exp':${expires_at},'iat':${issued_at},'sub':'${client_email}','target_audience':'${iap_client_id}'}"
  local payload_base64="$(echo "${payload}" | base64 | tr -d '\n')"

  # Create JWT signature using the private key
  local signature_base64="$(printf %s "${header_base64}.${payload_base64}" | openssl dgst -binary -sha256 -sign <(printf '%s\n' "${private_key}")  | base64 | tr -d '\n')"
  local assertion="${header_base64}.${payload_base64}.${signature_base64}"

  # Exchange the signed JWT assertion for an ID token
  local token_payload="$(curl -s \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
    --data-urlencode "assertion=${assertion}" \
    https://www.googleapis.com/oauth2/v4/token)"

  # Extract just the ID token from the response
  local bearer_id_token="$(echo "${token_payload}" | jq -r '.id_token')"
  echo "${bearer_id_token}"
}

main() {
  # Check if required arguments are provided
  if [[ $# -lt 3 ]]; then
    echo "Usage: $0 <service_account_key_file.json> <iap_client_id> <url>"
    exit 1
  fi

  # Assign parameters to variables
  SERVICE_ACCOUNT_KEY="$1"
  IAP_CLIENT_ID="$2"
  URL="$3"

  # Generate the ID token
  echo "Generating token..."
  ID_TOKEN=$(get_token "${SERVICE_ACCOUNT_KEY}" "${IAP_CLIENT_ID}")

  # Access the IAP-secured resource with the token
  echo "Accessing: ${URL}"
  curl --header "Authorization: Bearer ${ID_TOKEN}" "${URL}"
}

# Run the main function with all provided arguments
main "$@"

Dieses Skript führt die folgenden Schritte aus:

  1. Extrahieren der Dienstkontoschlüsselinformationen aus Ihrer JSON-Schlüsseldatei
  2. Erstellt ein JWT mit den erforderlichen Feldern, einschließlich der IAP-Client-ID als Zielgruppe.
  3. Signiert das JWT mit dem privaten Schlüssel des Dienstkontos.
  4. Tauscht dieses JWT über den OAuth-Dienst von Google gegen ein OIDC-Token ein.
  5. Verwendet das resultierende Token, um eine authentifizierte Anfrage an Ihre mit IAP gesicherte Ressource zu senden.

So verwenden Sie dieses Skript:

  1. Speichern Sie es in einer Datei, z. B. get_iap_token.sh.
  2. Ausführbar machen: chmod +x get_iap_token.sh
  3. Führen Sie sie mit drei Parametern aus:
  ./get_iap_token.sh service-account-key.json \
    OAUTH_CLIENT_ID \
    URL

Wobei:

  • service-account-key.json ist die heruntergeladene Dienstkonto-Schlüsseldatei.
  • OAUTH_CLIENT_ID ist die OAuth-Client-ID für Ihre mit IAP gesicherte Ressource.
  • URL ist die URL, auf die Sie zugreifen möchten.

In allen anderen Fällen ein OIDC-Token abrufen

In allen anderen Fällen können Sie mit der IAM Credentials API ein OIDC-Token generieren, indem Sie die Identität eines Zieldienstkontos direkt vor dem Zugriff auf eine mit IAP gesicherte Ressource übernehmen. Dieser Vorgang umfasst folgende Schritte:

  1. Weisen Sie dem aufrufenden Dienstkonto (dem Dienstkonto, das mit dem Code verknüpft ist, der das ID-Token abruft) die Rolle „Service Account OpenID Connect Identity Token Creator“ (roles/iam.serviceAccountOpenIdTokenCreator) zu.

    Dadurch kann das aufrufende Dienstkonto die Identität des Zieldienstkontos übernehmen.

  2. Rufen Sie mit den Anmeldedaten des aufrufenden Dienstkontos die Methode generateIdToken für das Zieldienstkonto auf.

    Geben Sie im Feld audience Ihre Client-ID an.

Eine detaillierte Anleitung finden Sie unter ID-Token erstellen.

Authentifizierung über den Proxy-Authorization-Header

Wenn Ihre Anwendung den Anfrageheader Authorization verwendet, können Sie das ID-Token stattdessen in einen Proxy-Authorization: Bearer-Header einfügen. Wenn ein gültiges ID-Token in einem Proxy-Authorization-Header gefunden wird, autorisiert IAP die Anfrage damit. Nach der Autorisierung der Anfrage übergibt IAP den Authorization-Header an Ihre Anwendung, ohne den Inhalt zu verarbeiten.

Wenn im Proxy-Authorization-Header kein gültiges ID-Token gefunden wird, wird der Authorization-Header von IAP weiterverarbeitet und der Proxy-Authorization-Header entfernt, bevor die Anfrage an Ihre Anwendung weitergeleitet wird.

Nächste Schritte