Einsatz von OAuth 2.0 für Server-zu-Server-Anwendungen

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.
Die Seite Weitere Informationen finden Sie in der Google Cloud Platform-Dokumentation unter Authentifizierung.

Das Google OAuth 2.0-System unterstützt Server-zu-Server-Interaktionen, z. B. zwischen einer Webanwendung und einem Google-Dienst. Für dieses Szenario benötigen Sie ein Dienstkonto. Dies ist ein Konto, das zu Ihrer Anwendung gehört, nicht zu einem einzelnen Endnutzer. Ihre Anwendung ruft Google APIs im Namen des Dienstkontos auf, sodass Nutzer nicht direkt beteiligt sind. Dieses Szenario wird manchmal als zweibeiniges OAuth oder 2LO bezeichnet. Der verwandte Begriff „dreibeiniges OAuth“ bezieht sich auf Szenarien, in denen Ihre Anwendung Google APIs im Namen von Endnutzern aufruft und manchmal die Zustimmung des Nutzers erforderlich ist.

In der Regel verwendet eine Anwendung ein Dienstkonto, wenn die Anwendung Google APIs verwendet, um mit eigenen Daten und nicht mit den Daten eines Nutzers zu arbeiten. Beispiel: Eine Anwendung, die Google Cloud Datastore für die Datenpersistenz verwendet, verwendet ein Dienstkonto, um ihre Aufrufe an die Google Cloud Datastore API zu authentifizieren.

Google Workspace-Domainadministratoren können auch Dienstkonten domainweite Berechtigungen gewähren, um im Namen von Nutzern in der Domain auf Nutzerdaten zuzugreifen.

In diesem Dokument wird beschrieben, wie eine Anwendung den Server-zu-Server-OAuth 2.0-Vorgang mithilfe einer Google APIs-Clientbibliothek (empfohlen) oder mit HTTP ausführen kann.

Übersicht

Erstellen Sie zur Unterstützung von Server-zu-Server-Interaktionen zuerst ein Dienstkonto in im Projekt. Wenn Sie auf Nutzerdaten für Nutzer in Ihrem Google Workspace-Konto zugreifen möchten, müssen Sie den domainweiten Zugriff auf das Dienstkonto delegieren.

Dann bereitet Ihre Anwendung die nötigen autorisierten API-Aufrufe vor. Dabei werden die Anmeldedaten des Dienstkontos verwendet, um ein Zugriffstoken vom OAuth 2.0-Authentifizierungsserver anzufordern.

Schließlich kann Ihre Anwendung das Zugriffstoken für den Aufruf von Google APIs verwenden.

Dienstkonto erstellen

Die Anmeldedaten eines Dienstkontos enthalten eine generierte E-Mail-Adresse, die eindeutig ist und mindestens ein Paar aus öffentlichem und privatem Schlüssel enthält. Wenn die domainweite Delegierung aktiviert ist, ist eine Client-ID auch Teil der Anmeldedaten des Dienstkontos.

Wenn Ihre Anwendung in Google App Engine ausgeführt wird, wird beim Erstellen Ihres Projekts automatisch ein Dienstkonto eingerichtet.

Wenn Ihre Anwendung in Google Compute Engine ausgeführt wird, wird beim Erstellen Ihres Projekts auch automatisch ein Dienstkonto eingerichtet. Sie müssen jedoch beim Erstellen einer Google Compute Engine-Instanz die Bereiche angeben, auf die Ihre Anwendung Zugriff benötigt. Weitere Informationen finden Sie unter Instanz für die Verwendung von Dienstkonten vorbereiten.

Wenn Ihre Anwendung nicht in Google App Engine oder Google Compute Engine ausgeführt wird, müssen Sie diese Anmeldedaten in den abrufen. So generieren Sie Dienstkonto-Anmeldedaten oder rufen die öffentlichen Anmeldedaten auf, die Sie bereits generiert haben:

Erstellen Sie zunächst ein Dienstkonto:

  1. Öffnen Sie den Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Klicken Sie auf Dienstkonto erstellen .
  4. Geben Sie unter Dienstkontodetails einen Namen, eine ID und eine Beschreibung für das Dienstkonto ein und klicken Sie dann auf Erstellen und fortfahren .
  5. Optional: Wählen Sie unter Diesem Dienstkonto Zugriff auf Projekt gewähren die IAM-Rollen aus, die dem Dienstkonto gewährt werden sollen.
  6. Klicken Sie auf Weiter .
  7. Optional: Fügen Sie unter Benutzern Zugriff auf dieses Dienstkonto gewähren die Benutzer oder Gruppen hinzu, die das Dienstkonto verwenden und verwalten dürfen.
  8. Klicken Sie auf Fertig .

Erstellen Sie als Nächstes einen Dienstkontoschlüssel:

  1. Klicken Sie auf die E-Mail-Adresse für das von Ihnen erstellte Dienstkonto.
  2. Klicken Sie auf die Registerkarte Schlüssel .
  3. Wählen Sie in der Dropdown-Liste Schlüssel hinzufügen die Option Neuen Schlüssel erstellen aus.
  4. Klicken Sie auf Erstellen .

Ihr neues öffentliches/privates Schlüsselpaar wird generiert und auf Ihren Computer heruntergeladen; es dient als einzige Kopie des privaten Schlüssels. Sie sind für die sichere Aufbewahrung verantwortlich. Wenn Sie dieses Schlüsselpaar verlieren, müssen Sie ein neues generieren.

Sie können jederzeit zum API Console zurückkehren, um die E-Mail-Adresse, Fingerabdrücke des öffentlichen Schlüssels und andere Informationen aufzurufen oder zusätzliche öffentliche/private Schlüsselpaare zu erstellen. Weitere Informationen zu Dienstkonto-Anmeldedaten in der API Consolesiehe Dienstkonten in der API ConsoleHilfedatei.

Notieren Sie sich die E-Mail-Adresse des Dienstkontos und speichern Sie die private Schlüsseldatei des Dienstkontos an einem Speicherort, auf den Ihre Anwendung Zugriff hat. Ihre Anwendung benötigt sie, um autorisierte API-Aufrufe auszuführen.

Domainweite Autorität an das Dienstkonto delegieren

Wenn Sie ein Google Workspace-Konto haben, kann ein Administrator der Organisation eine Anwendung autorisieren, im Namen von Nutzern in der Google Workspace-Domain auf Nutzerdaten zuzugreifen. Beispiel: Eine Anwendung, die die Google Calendar API zum Hinzufügen von Terminen zu den Kalendern aller Nutzer in einer Google Workspace-Domain verwendet, würde ein Dienstkonto verwenden, um im Namen der Nutzer auf die Google Calendar API zuzugreifen. Die Autorisierung eines Dienstkontos für den Zugriff auf Daten im Namen von Nutzern in einer Domain wird manchmal als „delegierte domainweite Befugnis“ an ein Dienstkonto bezeichnet.

Ein Super Admin der Google Workspace-Domain muss die folgenden Schritte ausführen, um domainweite Berechtigungen an ein Dienstkonto zu delegieren:

  1. Gehen Sie in der Admin-Konsole Ihrer Google Workspace-Domain zu Hauptmenü > Sicherheit > Zugriff und Datenkontrolle.
  2. Wählen Sie im Bereich Domainweite Delegierung die Option Domainweite Delegierung verwalten aus.
  3. Klicken Sie auf Neu hinzufügen.
  4. Geben Sie in das Feld Client-ID die Client-ID des Dienstkontos ein. Die Client-ID Ihres Dienstkontos finden Sie in der Service accounts page.
  5. Geben Sie im Feld OAuth-Bereiche (kommagetrennt) die Liste der Bereiche ein, auf die Ihre Anwendung Zugriff erhalten soll. Wenn Ihre Anwendung beispielsweise domainübergreifenden vollständigen Zugriff auf die Google Drive API und die Google Calendar API benötigt, geben Sie https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar ein.
  6. Klicken Sie auf Authorize (Autorisieren).

Ihre Anwendung ist nun befugt, API-Aufrufe als Nutzer in Ihrer Domain durchzuführen (um Nutzer zu stehlen). Wenn Sie autorisierte API-Aufrufe erstellen, geben Sie den entsprechenden Nutzer an.

Autorisierten API-Aufruf vorbereiten

Java

Nachdem Sie die Client-E-Mail-Adresse und den privaten Schlüssel von API Consoleabgerufen haben, verwenden Sie die Google APIs-Clientbibliothek für Java, um ein GoogleCredential-Objekt aus den Anmeldedaten des Dienstkontos und den Bereichen zu erstellen, auf die Ihre Anwendung Zugriff benötigt. Beispiel:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Wenn Sie eine Anwendung auf der Google Cloud Platform entwickeln, können Sie stattdessen die Standardanmeldedaten der Anwendung verwenden. Das vereinfacht den Vorgang.

Domainweite Befugnis delegieren

Wenn Sie den domainweiten Zugriff auf das Dienstkonto delegiert haben und die Identität eines Nutzerkontos übernehmen möchten, geben Sie die E-Mail-Adresse des Nutzerkontos mit der Methode createDelegated des Objekts GoogleCredential an. Beispiel:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

Verwenden Sie das Objekt GoogleCredential, um Google APIs in Ihrer Anwendung aufzurufen.

Python

Nachdem Sie die Client-E-Mail-Adresse und den privaten Schlüssel von API Consoleabgerufen haben, verwenden Sie die Google APIs-Clientbibliothek für Python, um die folgenden Schritte auszuführen:

  1. Erstellen Sie ein Credentials-Objekt aus den Anmeldedaten des Dienstkontos und den Bereichen, auf die Ihre Anwendung zugreifen muss. Beispiel:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Wenn Sie eine Anwendung auf der Google Cloud Platform entwickeln, können Sie stattdessen die Standardanmeldedaten der Anwendung verwenden. Das vereinfacht den Vorgang.

  2. Domainweite Befugnis delegieren

    Wenn Sie den domainweiten Zugriff auf das Dienstkonto delegiert haben und die Identität eines Nutzerkontos übernehmen möchten, verwenden Sie die Methode with_subject eines vorhandenen Objekts ServiceAccountCredentials. Beispiel:

    delegated_credentials = credentials.with_subject('user@example.org')

Verwenden Sie das Objekt „Anmeldedaten“, um Google APIs in Ihrer Anwendung aufzurufen.

HTTP/REST

Nachdem Sie die Client-ID und den privaten Schlüssel von API Consoleabgerufen haben, muss Ihre Anwendung die folgenden Schritte ausführen:

  1. Erstellen Sie ein JSON Web Token (JWT, ausgesprochen, "jot"), das einen Header, einen Anforderungssatz und eine Signatur enthält.
  2. Fordern Sie ein Zugriffstoken vom Google OAuth 2.0-Autorisierungsserver an.
  3. Verarbeitet die vom Autorisierungsserver zurückgegebene JSON-Antwort.

In den folgenden Abschnitten wird beschrieben, wie Sie diese Schritte ausführen.

Wenn die Antwort ein Zugriffstoken enthält, können Sie mit dem Zugriffstoken eine Google API aufrufen. Wenn die Antwort kein Zugriffstoken enthält, haben das JWT und die Tokenanfrage möglicherweise nicht das richtige Format oder das Dienstkonto ist nicht berechtigt, auf die angeforderten Bereiche zuzugreifen.

Wenn das Zugriffstoken abläuft, generiert Ihre Anwendung ein weiteres JWT, signiert es und fordert ein neues Zugriffstoken an.

Ihre Serveranwendung verwendet ein JWT, um ein Token vom Google Authorization Server anzufordern. Anschließend wird mithilfe des Tokens ein Google API-Endpunkt aufgerufen. Es ist kein Endnutzer beteiligt.

Im weiteren Verlauf dieses Abschnitts werden die Schritte zum Erstellen eines JWT, Signieren des JWT, Erstellen der Zugriffstokenanfrage und Verarbeiten der Antwort beschrieben.

JWT erstellen

Ein JWT besteht aus drei Teilen: einem Header, einem Anforderungssatz und einer Signatur. Der Header und der Anforderungssatz sind JSON-Objekte. Diese JSON-Objekte werden in UTF-8-Byte serialisiert und dann mit der Base64-URL-Codierung codiert. Diese Codierung sorgt für Ausfallsicherheit bei Codierungsänderungen aufgrund wiederholter Codierungsvorgänge. Der Header, der Anspruchssatz und die Signatur werden mit einem Punkt (.) verkettet.

Ein JWT setzt sich so zusammen:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

Der Basisstring für die Signatur sieht so aus:

{Base64url encoded header}.{Base64url encoded claim set}
JWT-Header erstellen

Der Header besteht aus zwei Feldern, die den Signaturalgorithmus und das Format der Assertion angeben. Beide Felder sind obligatorisch und jedes Feld hat nur einen Wert. Dieser Header ändert sich entsprechend der Algorithmen und Formate.

Dienstkonten basieren auf dem RSA-SHA-256-Algorithmus und dem JWT-Tokenformat. Die JSON-Darstellung des Headers sieht also so aus:

{"alg":"RS256","typ":"JWT"}

Die Base64url-Darstellung sieht so aus:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
JWT-Anforderungssatz erstellen

Der JWT-Anforderungssatz enthält Informationen zum JWT, einschließlich der angeforderten Berechtigungen (Bereiche), dem Ziel des Tokens, dem Aussteller, der Zeit, zu der das Token ausgestellt wurde, und der Lebensdauer des Tokens. Die meisten Felder sind Pflichtfelder. Wie der JWT-Header ist der JWT-Anforderungssatz ein JSON-Objekt und wird bei der Berechnung der Signatur verwendet.

Erforderliche Ansprüche

Die erforderlichen Ansprüche im JWT-Anforderungssatz sind unten aufgeführt. Sie können in einer beliebigen Reihenfolge im Anspruchssatz vorkommen.

Name Beschreibung
iss Die E-Mail-Adresse des Dienstkontos.
scope Eine durch Leerzeichen getrennte Liste der Berechtigungen, die von der Anwendung angefordert werden.
aud Eine Beschreibung des beabsichtigten Ziels der Assertion. Wenn Sie ein Zugriffstoken anfordern, lautet dieser Wert immer https://oauth2.googleapis.com/token.
exp Die Ablaufzeit der Assertion, angegeben in Sekunden seit 00:00:00 UTC, 1. Januar 1970. Dieser Wert ist nach der Ausstellung maximal 1 Stunde lang gültig.
iat Der Zeitpunkt, an dem die Assertion erstellt wurde, angegeben in Sekunden seit dem 1. Januar 1970 um 00:00:00 UTC.

Im Folgenden sehen Sie die JSON-Darstellung der Pflichtfelder in einem JWT-Anforderungssatz:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Zusätzliche Ansprüche

In einigen Unternehmensfällen kann eine Anwendung die domainweite Delegierung nutzen, um im Namen eines bestimmten Nutzers in einer Organisation zu handeln. Die Berechtigung zum Ausführen dieser Art von Identitätswechsel muss gewährt werden, bevor eine Anwendung die Identität eines Nutzers übernehmen kann. Sie wird normalerweise von einem Super Admin verwaltet. Weitere Informationen finden Sie unter API-Zugriff mit domainübergreifender Delegierung steuern.

Um ein Zugriffstoken zu erhalten, das einer Anwendung delegierten Zugriff auf eine Ressource gewährt, geben Sie die E-Mail-Adresse des Nutzers in die JWT-Anforderung ein, die als Wert im Feld sub festgelegt ist.

Name Beschreibung
sub Die E-Mail-Adresse des Nutzers, für den die Anwendung den delegierten Zugriff anfordert.

Wenn eine Anwendung nicht berechtigt ist, die Identität eines Nutzers zu übernehmen, wird als Antwort auf eine Zugriffstokenanfrage mit dem Feld sub ein Fehler ausgegeben.

Hier ein Beispiel für einen JWT-Anforderungssatz mit dem Feld sub:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
JWT-Anforderungssatz codieren

Wie der JWT-Header sollte auch der JWT-Anforderungssatz in UTF-8 und Base64url-sicher codiert sein. Hier ein Beispiel für eine JSON-Darstellung eines JWT-Anforderungssatzes:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Signatur berechnen

Die JSON-Websignatur (JWS) ist die Spezifikation, die den Mechanismus zum Generieren der Signatur für das JWT steuert. Die Eingabe für die Signatur ist das Byte-Array des folgenden Inhalts:

{Base64url encoded header}.{Base64url encoded claim set}

Der Signaturalgorithmus im JWT-Header muss beim Berechnen der Signatur verwendet werden. Der einzige Signaturalgorithmus, der vom Google OAuth 2.0 Authorization Server unterstützt wird, ist RSA, die den SHA-256-Hash-Algorithmus verwendet. Dies wird im Feld alg im JWT-Header als RS256 ausgedrückt.

Signieren Sie die UTF-8-Darstellung der Eingabe mit SHA256withRSA (auch RSASSA-PKCS1-V1_5-SIGN mit der SHA-256-Hash-Funktion genannt) mit dem privaten Schlüssel aus Google API Console. Als Ausgabe erhalten Sie ein Byte-Array.

Die Signatur muss dann Base64url-codiert sein. Der Header, der Anforderungssatz und die Signatur werden mit einem Punkt (.) verkettet. Das Ergebnis ist das JWT. Zur Verdeutlichung sollten die folgenden Zeilenumbrüche verwendet werden:

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Hier ist ein Beispiel für ein JWT vor der Base64-URL-Codierung:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Hier ein Beispiel für ein JWT, das signiert wurde und übertragen werden kann:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Zugriffstokenanfrage stellen

Nachdem das signierte JWT generiert wurde, kann eine Anwendung es verwenden, um ein Zugriffstoken anzufordern. Diese Zugriffstokenanfrage ist eine HTTPS-POST-Anfrage und der Text ist URL-codiert. Die URL sieht so aus:

https://oauth2.googleapis.com/token

Die folgenden Parameter sind in der HTTPS-POST-Anfrage erforderlich:

Name Beschreibung
grant_type Verwenden Sie den folgenden String, der nach Bedarf URL-codiert ist: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion Das JWT, einschließlich Signatur.

Hier ist ein Roh-Dump der HTTPS-POST-Anfrage, die in einer Zugriffstokenanfrage verwendet wird:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Hier ist dieselbe Anfrage mit curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Antwort verarbeiten

Wenn die JWT- und Zugriffstokenanfrage korrekt formatiert sind und das Dienstkonto die Berechtigung zum Ausführen des Vorgangs hat, enthält die JSON-Antwort des Autorisierungsservers ein Zugriffstoken. Hier eine Beispielantwort:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

Zugriffstokens können während des Dauerfensters wiederverwendet werden, das durch den Wert expires_in angegeben wird.

Google APIs aufrufen

Java

Verwenden Sie das Objekt GoogleCredential, um Google APIs aufzurufen. Führen Sie dazu diese Schritte aus:

  1. Erstellen Sie mit dem Objekt GoogleCredential ein Dienstobjekt für die API, die Sie aufrufen möchten. Beispiel:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Senden Sie Anfragen an den API-Dienst über die Schnittstelle, die vom Dienstobjekt zur Verfügung gestellt wird. So listen Sie beispielsweise die Instanzen von Cloud SQL-Datenbanken im Projekt „ spannend-example-123“ auf:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Führe die folgenden Schritte aus, um Google APIs mit dem autorisierten Credentials-Objekt aufzurufen:

  1. Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten. Zum Erstellen eines Dienstobjekts rufen Sie die Funktion build mit dem Namen und der Version der API und dem autorisierten Objekt Credentials auf. So rufen Sie beispielsweise Version 1beta3 der Cloud SQL Administration API auf:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. Senden Sie Anfragen an den API-Dienst über die Schnittstelle, die vom Dienstobjekt zur Verfügung gestellt wird. So listen Sie beispielsweise die Instanzen von Cloud SQL-Datenbanken im Projekt „ spannend-example-123“ auf:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Nachdem Ihre Anwendung ein Zugriffstoken erhalten hat, können Sie damit im Namen eines bestimmten Dienstkontos oder Nutzerkontos Aufrufe an eine Google API senden, sofern der/die von der API erforderlichen Zugriffsberechtigungen gewährt wurden. Füge dazu das Zugriffstoken in eine Anfrage an die API ein. Füge dazu den access_token-Abfrageparameter oder den Authorization-HTTP-Headerwert Bearer hinzu. Wenn möglich, ist der HTTP-Header zu bevorzugen, da Abfragestrings in der Regel in Serverlogs sichtbar sind. In den meisten Fällen kannst du eine Clientbibliothek verwenden, um deine Aufrufe an Google APIs einzurichten (z. B. beim Aufruf der Drive Files API).

Sie können alle Google APIs ausprobieren und sich ihre Bereiche im OAuth 2.0 Playground ansehen.

Beispiele für HTTP GET

Ein Aufruf des Endpunkts drive.files (Drive Drive API) über den HTTP-Header Authorization: Bearer könnte so aussehen. Sie müssen ein eigenes Zugriffstoken angeben:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Hier ist ein Aufruf an die gleiche API für den authentifizierten Nutzer mit dem Abfragestringparameter access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Beispiele für curl

Sie können diese Befehle mit der curl-Befehlszeile testen. Hier ein Beispiel, bei dem die HTTP-Header-Option (bevorzugt) verwendet wird:

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Alternativ können Sie die folgende Parameteroption für den Abfragestring verwenden:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Ablauf von Zugriffstokens

Zugriffstokens, die vom Google OAuth 2.0 Authorization Server ausgestellt wurden, laufen nach der vom expires_in-Wert angegebenen Dauer ab. Wenn ein Zugriffstoken abläuft, sollte die Anwendung ein weiteres JWT generieren, es signieren und ein neues Zugriffstoken anfordern.

JWT-Fehlercodes

Feld error Feld error_description Bedeutung Problemlösung
unauthorized_client Unauthorized client or scope in request. Wenn Sie die domainweite Delegierung verwenden möchten, ist das Dienstkonto in der Admin-Konsole der Nutzerdomain nicht autorisiert.

Prüfen Sie, ob das Dienstkonto auf der Seite Domainweite Delegierung der Admin-Konsole für den Nutzer im Anspruch sub (Feld) autorisiert ist.

Die Autorisierung dauert in der Regel einige Minuten. Es kann jedoch bis zu 24 Stunden dauern, bis die Autorisierung für alle Nutzer in Ihrem Google-Konto wirksam wird.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Ein Dienstkonto wurde mit der Client-E-Mail-Adresse anstelle der Client-ID (numerisch) in der Admin-Konsole autorisiert. Entfernen Sie auf der Seite Domainweite Delegierung in der Admin-Konsole den Client und fügen Sie ihn mit der numerischen ID wieder hinzu.
access_denied (beliebiger Wert) Wenn Sie die domainweite Delegierung verwenden, sind mindestens ein angeforderter Bereich in der Admin-Konsole nicht autorisiert.

Achten Sie darauf, dass das Dienstkonto in der Admin-Konsole auf der Seite Domainweite Delegierung für den Nutzer im Anspruch sub (Feld) autorisiert ist. Außerdem muss es alle Bereiche enthalten, die Sie im scope-Anspruch Ihres JWT anfordern.

Die Autorisierung dauert in der Regel einige Minuten. Es kann jedoch bis zu 24 Stunden dauern, bis die Autorisierung für alle Nutzer in Ihrem Google-Konto wirksam wird.

invalid_grant Not a valid email. Der Nutzer ist nicht vorhanden. Prüfe, ob die E-Mail-Adresse im Feld „sub“ korrekt ist.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Normalerweise bedeutet das, dass die lokale Systemzeit falsch ist. Es kann aber auch passieren, wenn der Wert exp dem zukünftigen Wert von iat mehr als 65 Minuten in der Zukunft entspricht oder der Wert von exp niedriger als der Wert von iat ist.

Prüfen Sie, ob die Uhrzeit des Systems, auf dem das JWT generiert wird, korrekt ist. Synchronisiere gegebenenfalls deine Zeit mit Google NTP.

invalid_grant Invalid JWT Signature.

Die JWT-Assertion ist mit einem privaten Schlüssel signiert, der nicht mit dem Dienstkonto verknüpft ist, das durch die Client-E-Mail-Adresse identifiziert wird, oder der verwendete Schlüssel gelöscht oder deaktiviert wurde oder abgelaufen ist.

Es ist auch möglich, dass die JWT-Assertion falsch codiert ist. Sie muss Base64-codiert sein und keine Zeilenumbrüche oder Padding enthalten.

Decodieren Sie den JWT-Anforderungssatz und prüfen Sie den Schlüssel, der die Assertion signiert hat, mit dem Dienstkonto.

Verwenden Sie eine von Google bereitgestellte OAuth-Bibliothek, damit das JWT korrekt generiert wird.

invalid_scope Invalid OAuth scope or ID token audience provided. Es wurden keine Bereiche angefordert (leere Liste der Bereiche) oder einer der angeforderten Bereiche ist nicht vorhanden (d.h. ist ungültig).

Achten Sie darauf, dass die scope-Anforderung (Feld) des JWT gefüllt ist und vergleichen Sie die Bereiche, die sie enthalten, mit den dokumentierten Bereichen für die APIs, die Sie verwenden möchten, um sicherzustellen, dass es keine Fehler oder Tippfehler gibt.

Die Liste der Bereiche in der scope-Anforderung muss durch Leerzeichen und nicht durch Kommas getrennt werden.

disabled_client The OAuth client was disabled. Der Schlüssel, der zum Signieren der JWT-Assertion verwendet wird, ist deaktiviert.

Rufen Sie die Google API Consoleauf und aktivieren Sie unter IAM & Verwaltung; Dienstkonten das Dienstkonto, das die Schlüssel-ID enthält, mit der die Assertion signiert wird.

Ergänzung: Dienstkontoautorisierung ohne OAuth

Bei einigen Google APIs können Sie autorisierte API-Aufrufe direkt mit einem signierten JWT als Inhabertoken anstelle eines OAuth 2.0-Zugriffstokens ausführen. So können Sie vermeiden, dass vor dem API-Aufruf eine Netzwerkanfrage an den Autorisierungsserver von Google gesendet werden muss.

Wenn für die API, die Sie aufrufen möchten, eine Dienstdefinition im GitHub-Repository von Google APIs veröffentlicht ist, können Sie autorisierte API-Aufrufe mit einem JWT anstelle eines Zugriffstokens ausführen. Anleitung:

  1. Erstellen Sie wie oben beschrieben ein Dienstkonto. Behalten Sie unbedingt die JSON-Datei, die Sie beim Erstellen des Kontos erhalten.
  2. Erstellen Sie mit einer beliebigen JWT-Standardbibliothek, z. B. einer unter jwt.io, ein JWT mit einem Header und einer Nutzlast wie im folgenden Beispiel:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Geben Sie im Feld kid im Header die private Schlüssel-ID Ihres Dienstkontos an. Sie finden diesen Wert im Feld private_key_id der JSON-Datei Ihres Dienstkontos.
    • Geben Sie für die Felder iss und sub die E-Mail-Adresse Ihres Dienstkontos an. Sie finden diesen Wert im Feld client_email der JSON-Datei Ihres Dienstkontos.
    • Geben Sie im Feld aud den API-Endpunkt an. Beispiel: https://SERVICE.googleapis.com/.
    • Geben Sie für das Feld iat die aktuelle Unix-Zeit und für das Feld exp die Zeit genau 3.600 Sekunden später an, wenn die JWT abläuft.

Signieren Sie das JWT mit RSA-256, indem Sie den privaten Schlüssel aus der JSON-Datei Ihres Dienstkontos verwenden.

Beispiel:

Java

Mit google-api-java-client und java-jwt:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

Mit PyJWT:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Rufen Sie die API mit dem signierten JWT als Inhabertoken auf:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com