Programmatische Authentifizierung

In diesem Dokument wird beschrieben, wie Sie sich über ein Nutzerkonto oder ein Dienstkonto bei einer IAP-gesicherten Ressource authentifizieren.

Der programmatische Zugriff bezieht sich auf den Aufruf von durch IAP gesicherten Anwendungen von Nicht-Browser-Clients wie Befehlszeilentools, Dienst-zu-Dienst-Aufrufen und mobilen Anwendungen. Je nach Anwendungsfall können Sie sich mit Nutzeranmeldedaten oder Dienstanmeldedaten 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. Sie authentifizieren ein Dienstkonto, 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 die Zielgruppenanforderung 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.

Fügen Sie diese Anmeldedaten für IAP im HTTP-Header Authorization oder Proxy-Authorization der Anfrage ein.

Hinweis

  1. Sie benötigen eine Anwendung, auf die Sie programmatisch über ein Entwicklerkonto, ein Dienstkonto oder die Anmeldedaten einer mobilen App zugreifen möchten.

  2. Informationen zum Erstellen eines oder mehrerer OAuth 2.0-Clients finden Sie unter Programmatischer Zugriff.

Nutzerkonto authentifizieren

Sie können den Nutzerzugriff auf Ihre Anwendung über eine Desktop- oder mobile App aktivieren, damit ein Programm mit einer IAP-gesicherten Ressource interagieren kann.

Über eine mobile App authentifizieren

  1. Erstellen oder verwenden Sie eine vorhandene OAuth 2.0-Client-ID für Ihre mobile App. 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 auf die Anwendung hinzu.
  2. Rufen Sie ein ID-Token für die OAuth 2.0-Client-ID der IAP-geschützten Ressource ab.
  3. Fügen Sie das ID-Token in einen Authorization: Bearer-Header ein, um die authentifizierte Anfrage an die IAP-gesicherte Ressource zu senden.

Über eine Desktop-Anwendung 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, erstellen Sie eine OAuth 2.0-Client-ID für Computer oder geben Sie eine vorhandene OAuth-Client-ID für Computer frei.
  2. Fügen Sie die OAuth-ID der Zulassungsliste für den programmatischen Zugriff für die Anwendung hinzu.

In der Anwendung anmelden

Jeder Entwickler muss sich anmelden, um auf eine durch IAP gesicherte Anwendung zuzugreifen. Sie können den Prozess in ein Skript verpacken, 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 Ressource Google Cloud hat.
  2. Starten Sie einen lokalen Server, der die eingehenden Anfragen zurückgeben 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-Anwendung 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 Wert CODE, um CODE im folgenden Befehl zu ersetzen, zusammen mit der Client-ID und dem Secret der Desktop-Anwendung:

      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 einem id_token-Feld zurück, über das Sie auf die Anwendung zugreifen können.

Auf die Anwendung zugreifen

Verwenden Sie die id_token, um auf die App zuzugreifen:

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

Aktualisierungstoken

Sie können das während des Anmeldevorgangs generierte Aktualisierungstoken verwenden, um neue ID-Tokens abzurufen. Das ist nützlich, wenn das ursprüngliche ID-Token abläuft. Jedes ID-Token ist etwa eine Stunde lang gültig. Während dieser Zeit können Sie mehrere Anfragen an eine bestimmte Anwendung senden.

Im folgenden Beispiel wird curl verwendet, um mit dem Aktualisierungstoken ein neues ID-Token abzurufen. 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, über das Sie auf die Anwendung zugreifen können.

Dienstkonto authentifizieren

Sie können ein Dienstkonto-JWT oder ein OpenID Connect-Token (OIDC) verwenden, um ein Dienstkonto bei einer 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 die Funktion „Kontextsensitiver 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 Workforce Identity-Föderation konfigurierte Anwendungen.

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

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

    Mit der Rolle erhalten Hauptkonten die Berechtigung, kurzlebige Anmeldedaten wie JWTs zu erstellen.

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

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

JWT erstellen

Das erstellte JWT sollte eine Nutzlast ähnlich dem folgenden Beispiel haben:

{
  "iss": SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "sub": SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "aud": TARGET_URL,
  "iat": IAT,
  "exp": EXP,
}
  • Geben Sie in den Feldern iss und sub die E-Mail-Adresse des Dienstkontos an. Die E-Mail-Adresse befindet sich im Feld client_email der JSON-Datei des Dienstkontos oder wird als Eingabe bereitgestellt. Typisches Format: service-account@PROJECT_ID.iam.gserviceaccount.com

  • Geben Sie im Feld aud die genaue URL oder die URL mit einem Pfad-Platzhalter (/*) der IAP-gesicherten Ressource an, z. B. https://example.com/ oder https://example.com/*. Ein JWT mit der genauen URL im Feld aud kann nur auf diese bestimmte URL zugreifen. Ein JWT mit dem Pfad-Platzhalter (/*) im Feld aud kann auf alle URLs zugreifen, die das Präfix aud ohne das nachgestellte * haben.

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

JWT signieren

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

  • Verwenden Sie die IAM Credentials API, um ein JWT zu 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. Die Methode ruft den privaten Schlüssel ab, der Ihrem Dienstkonto zugeordnet ist, und verwendet ihn, um die JWT-Nutzlast zu signieren. Dadurch kann ein JWT ohne direkten Zugriff auf einen privaten Schlüssel signiert werden.

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 the service account that the
        JWT is created for.
        resource_url (str): Specifies the 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-secured application.

    Returns:
        str: A signed JWT that can be used to access IAP-secured applications.
            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.
    # Project should always be "-".
    # Replacing the wildcard character with a project ID is invalid.
    name = iam_client.service_account_path("-", 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 aus einer lokalen Datei mit Anmeldedatenschlüsseln signieren

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

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

Wenn Sie das JWT lokal signieren, fügen Sie der Nutzlast einen JWT-Header hinzu. 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 private Schlüssel aus der Datei wird zum Signieren des JWT verwendet.

Auf die Anwendung zugreifen

Fügen Sie das signierte JWT in den Autorisierungsheader ein, um auf die Anwendung zuzugreifen:

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

Mit einem OIDC-Token für ein Dienstkonto authentifizieren

So authentifizieren Sie sich mit einem OIDC-Token für ein Dienstkonto:

  1. Erstellen Sie eine neue OIDC-Client-ID oder verwenden Sie eine vorhandene.

    • So erstellen Sie eine neue OAuth 2.0-Client-ID:

      1. Falls noch nicht geschehen, müssen Sie Ihre Anwendung für die Verwendung von Google Auth registrieren.

      2. Rufen Sie die Seite „Google Auth Platform“ auf.

        Zur Google Auth Platform

        Wenn Sie kein Projekt ausgewählt haben, werden Sie aufgefordert, eines zu erstellen.

      3. Klicken Sie auf Client erstellen.

      4. Wählen Sie den entsprechenden Anwendungstyp aus und geben Sie alle erforderlichen zusätzlichen Informationen ein.

      5. Geben Sie die erforderlichen Informationen für den ausgewählten Clienttyp ein. Klicken Sie auf Erstellen, um den Client zu erstellen.

    • So verwenden Sie eine vorhandene OAuth 2.0-Client-ID: Folgen Sie der Anleitung unter OAuth-Clients freigeben.

  2. Fügen Sie die OAuth-ID der Zulassungsliste für den programmatischen Zugriff für die Anwendung hinzu.

  3. Achten Sie darauf, dass das Standarddienstkonto der Zugriffsliste für das IAP-gesicherte Projekt hinzugefügt wurde.

Wenn Sie Anfragen an die IAP-gesicherte Ressource senden, müssen Sie das Token im Authorization-Header angeben: Authorization: 'Bearer OIDC_TOKEN'

In den folgenden Codebeispielen wird gezeigt, wie Sie ein OIDC-Token abrufen.

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, verwenden Sie das folgende Codebeispiel, um ein Token für den Zugriff auf eine IAP-gesicherte Ressource zu generieren:

C#

Richten Sie zur Authentifizierung bei IAP die 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 Dienstkontoschlüsseldatei abrufen

Wenn Sie ein OIDC-Token mit einer Dienstkonto-Schlüsseldatei generieren möchten, erstellen und signieren Sie eine JWT-Assertion mit der Schlüsseldatei und tauschen Sie diese Assertion dann gegen ein ID-Token aus. 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 Script führt die folgenden Schritte aus:

  1. Extrahiert die Informationen zum Dienstkontoschlüssel 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 aus.
  5. Verwendet das resultierende Token, um eine authentifizierte Anfrage an Ihre IAP-gesicherte Ressource zu senden

So verwenden Sie dieses Script:

  1. Speichern Sie sie in einer Datei, z. B. get_iap_token.sh.
  2. Machen Sie sie ausführbar: chmod +x get_iap_token.sh
  3. Führen Sie ihn 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 IAP-gesicherte Ressource.
  • URL ist die URL, auf die Sie zugreifen möchten.

OIDC-Token durch Identitätsübernahme des Dienstkontos abrufen

In allen anderen Fällen verwenden Sie die IAM Credentials API, um ein OIDC-Token zu generieren. Dazu übernehmen Sie die Identität eines Zieldienstkontos, bevor Sie auf eine IAP-gesicherte Ressource zugreifen. 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. Verwenden Sie die Anmeldedaten des aufrufenden Dienstkontos, um die Methode generateIdToken für das Zieldienstkonto aufzurufen.

    Legen Sie im Feld audience Ihre Client-ID fest.

Eine detaillierte Anleitung finden Sie unter ID-Token erstellen.

Über Proxy-Authorization-Header authentifizieren

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, verarbeitet IAP weiterhin den Authorization-Header und entfernt den Proxy-Authorization-Header, bevor die Anfrage an Ihre Anwendung weitergeleitet wird.

Auf die Anwendung zugreifen

Führen Sie den folgenden Befehl aus, um mit dem Header Proxy-Authorization auf die Anwendung zuzugreifen:

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

Nächste Schritte