App mit signierten Headern sichern

Auf dieser Seite wird beschrieben, wie Sie Ihre Anwendung mit signierten IAP-Headern schützen können. Bei entsprechender Konfiguration sorgt Identity-Aware Proxy (IAP) mit JSON-Web-Tokens (JWTs) dafür, dass eine Anfrage an Ihre Anwendung autorisiert ist. So schützen Sie Ihre Anwendung vor folgenden Risiken:

  • IAP ist versehentlich deaktiviert
  • Fehlkonfigurierte Firewalls
  • Unbefugter Zugriff aus dem Projekt

Um Ihre Anwendung zu schützen, müssen Sie für alle Anwendungstypen signierte Header verwenden.

Wenn Sie mit einer App Engine-Standardumgebung arbeiten, können Sie auch die User API verwenden.

Die Systemdiagnosen von Compute Engine und GKE enthalten keine JWT-Header und IAP verarbeitet keine Systemdiagnosen. Wenn bei der Systemdiagnose Zugriffsfehler zurückgegeben werden, müssen Sie prüfen, ob sie in der Google Cloud console korrekt konfiguriert wurde und ob der Pfad der Systemdiagnose für die Validierung der JWT-Header zulässig ist. Weitere Informationen finden Sie unter Ausnahme für Systemdiagnose erstellen.

Hinweis

Um Ihre Anwendung mit signierten Headern zu schützen, muss Folgendes vorhanden sein:

Anwendung mit IAP-Headern schützen

Für den Schutz Ihrer Anwendung mit dem IAP-JWT müssen Sie den Header, die Nutzlast und die Signatur des JWT prüfen. Das JWT befindet sich im HTTP-Anfrageheader x-goog-iap-jwt-assertion. Wenn ein Angreifer IAP umgeht, kann er die nicht signierten IAP-Identitäts-Header x-goog-authenticated-user-{email,id} fälschen. Das IAP-JWT stellt dazu eine sicherere Alternative dar.

Signierte Header bieten eine sekundäre Sicherheit, wenn jemand IAP umgeht. Wenn IAP aktiviert ist, werden die vom Client bereitgestellten x-goog-*-Header entfernt, wenn die Anfrage über die IAP-Bereitstellungsinfrastruktur ausgeführt wird.

JWT-Header prüfen

Prüfen Sie, ob der Header des JWT den folgenden Anforderungen genügt:

Anforderungen an den JWT-Header
alg Algorithmus ES256
kid Schlüssel-ID Muss einem der öffentlichen Schlüssel entsprechen, die in der IAP-Schlüsseldatei aufgeführt und in zwei verschiedenen Formaten verfügbar sind: https://www.gstatic.com/iap/verify/public_key und https://www.gstatic.com/iap/verify/public_key-jwk

Achten Sie darauf, dass das JWT mit dem privaten Schlüssel signiert wurde, der der kid-Anforderung des Tokens entspricht. Rufen Sie zuerst den öffentlichen Schlüssel von einer der folgenden URLs ab:

  • https://www.gstatic.com/iap/verify/public_key. Diese URL enthält ein JSON-Wörterbuch, das die kid-Anforderungen den öffentlichen Schlüsselwerten zuordnet.
  • https://www.gstatic.com/iap/verify/public_key-jwk. Diese URL enthält die öffentlichen IAP-Schlüssel im JWK-Format.

Nachdem Sie den öffentlichen Schlüssel haben, verwenden Sie eine JWT-Bibliothek, um die Signatur zu prüfen.

IAP rotiert seine öffentlichen Schlüssel regelmäßig. Informationen dazu, wie Sie die JWTs immer prüfen können, finden Sie unter Automatisches Caching öffentlicher Schlüssel.

JWT-Nutzlast prüfen

Prüfen Sie, ob die Nutzlast des JWT den folgenden Anforderungen genügt:

Anforderungen an die JWT-Nutzlast
exp Ablaufzeit Muss in der Zukunft liegen. Die Zeit wird in Sekunden seit der UNIX-Epoche gemessen. Rechnen Sie rund 30 Sekunden Verzögerung ein. Die maximale Lebensdauer eines Tokens beträgt 10 Minuten + 2 * Verzögerung.
iat Ausstellungszeit Muss in der Vergangenheit liegen.j Die Zeit wird in Sekunden seit der UNIX-Epoche gemessen. Rechnen Sie rund 30 Sekunden Verzögerung ein.
aud Zielgruppe Muss ein String mit den folgenden Werten sein:
  • App Engine: /projects/PROJECT_NUMBER/apps/PROJECT_ID
  • Compute Engine und GKE: /projects/PROJECT_NUMBER/global/backendServices/SERVICE_ID
  • Cloud Run: /projects/PROJECT_NUMBER/locations/REGION/services/SERVICE_NAME
iss Aussteller Muss https://cloud.google.com/iap sein.
hd Kontodomain Wenn ein Konto zu einer gehosteten Domain gehört, wird die hd Anforderung bereitgestellt, um die Domain, der das Konto zugeordnet ist, identifizieren zu können.
google Google-Anforderung Wenn eine oder mehrere Zugriffsstufen auf die Anfrage angewendet werden, werden ihre Namen im JSON-Objekt der google Anforderung unter dem Schlüssel access_levels als Array von Strings gespeichert.

Wenn Sie eine Geräterichtlinie angeben und die Organisation Zugriff auf die Gerätedaten hat, wird die DeviceId ebenfalls im JSON-Objekt gespeichert. Bei einer Anfrage an eine andere Organisation hat diese möglicherweise keine Berechtigung zum Aufrufen der Gerätedaten.

Sie können die Werte für den aud oben erwähnten String über die Google Cloud console oder das gcloud-Befehlszeilentool abrufen.

So rufen Sie die aud Stringwerte von der Google Cloud console ab: Öffnen Sie die Identity-Aware Proxy-Einstellungen für Ihr Projekt und klicken Sie neben der Load-Balancer-Ressource auf das Dreipunkt-Menü. Wählen Sie dann Signed Header JWT Audience (Zielgruppe für JWT mit signiertem Header) aus. Im daraufhin angezeigten Dialogfeld Signed Header JWT wird die aud-Anforderung für die ausgewählte Ressource angezeigt.

Wenn Sie die aud-Stringwerte mit dem gcloud CLI gcloud-Befehlszeilentool abrufen möchten, müssen Sie die Projekt-ID kennen. Sie finden die Projekt-ID auf der Google Cloud console Projektinformationen Karte. Führen Sie dann für jeden Wert die angegebenen Befehle aus.

Projektnummer

Um mit dem gcloud-Befehlszeilentool die Projekt-ID abzurufen, führen Sie den folgenden Befehl aus:

gcloud projects describe PROJECT_ID

Der Befehl gibt in etwa Folgendes zurück:

createTime: '2016-10-13T16:44:28.170Z'
lifecycleState: ACTIVE
name: project_name
parent:
  id: '433637338589'
  type: organization
projectId: PROJECT_ID
projectNumber: 'PROJECT_NUMBER'

Dienst-ID

Um mit dem gcloud-Befehlszeilentool die Dienst-ID abzurufen, führen Sie den folgenden Befehl aus:

gcloud compute backend-services describe SERVICE_NAME --project=PROJECT_ID --global

Der Befehl gibt in etwa Folgendes zurück:

affinityCookieTtlSec: 0
backends:
- balancingMode: UTILIZATION
  capacityScaler: 1.0
  group: https://www.googleapis.com/compute/v1/projects/project_name/regions/us-central1/instanceGroups/my-group
connectionDraining:
  drainingTimeoutSec: 0
creationTimestamp: '2017-04-03T14:01:35.687-07:00'
description: ''
enableCDN: false
fingerprint: zaOnO4k56Cw=
healthChecks:
- https://www.googleapis.com/compute/v1/projects/project_name/global/httpsHealthChecks/my-hc
id: 'SERVICE_ID'
kind: compute#backendService