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

181 Weitere Informationen finden Sie in der Google Cloud Platform-Dokumentation unter Authentifizierung.

Das Google OAuth 2.0-System unterstützt Server-zu-Server-Interaktionen wie solche zwischen einer Webanwendung und einem Google-Dienst. Für dieses Szenario benötigen Sie ein Dienstkonto, also 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 OAuth-, 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 die Nutzereinwilligung manchmal erforderlich ist.

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

Google Workspace-Domainadministratoren können Dienstkonten auch domainweite Berechtigungen erteilen, um im Namen der Nutzer in der Domain auf Nutzerdaten zuzugreifen.

In diesem Dokument wird beschrieben, wie eine Anwendung den OAuth 2.0-Vorgang für Server-zu-Server mithilfe einer Google API-Clientbibliothek (empfohlen) oder HTTP abschließen kann.

Übersicht

Erstellen Sie zuerst ein Dienstkonto in der , um Server-zu-Server-Interaktionen zu unterstützen. Wenn Sie auf Nutzerdaten für Nutzer in Ihrem Google Workspace-Konto zugreifen möchten, delegieren Sie den domainweiten Zugriff auf das Dienstkonto.

Anschließend bereitet Ihre Anwendung autorisierte 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 verwenden, um Google APIs aufzurufen.

Dienstkonto erstellen

Die Anmeldedaten eines Dienstkontos enthalten eine eindeutige E-Mail-Adresse, die eindeutig ist und mindestens ein öffentliches/privates Schlüsselpaar enthält. Wenn die domainweite Delegierung aktiviert ist, ist eine Client-ID auch Teil der Anmeldedaten des Dienstkontos.

Wenn Ihre Anwendung auf 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 deine Anwendung nicht in Google App Engine oder Google Compute Engine ausgeführt wird, musst du diese Anmeldedaten in der abrufen. Gehen Sie so vor, um Dienstkonto-Anmeldedaten zu generieren oder die öffentlichen Anmeldedaten aufzurufen, die Sie bereits generiert haben:

首先,创建一个服务帐户:

  1. 打开 Service accounts page
  2. If prompted, select a project, or create a new one.
  3. 点击创建服务帐户
  4. 服务帐户的详细信息,键入一个名称,ID和服务帐户的描述,然后单击创建并继续
  5. 可选:在授予此服务帐户访问到项目中,选择IAM角色授予服务帐户。
  6. 点击继续
  7. 可选:在授予用户访问该服务帐户,添加允许使用和管理服务帐户的用户或组。
  8. 点击完成
  9. 点击创建键,然后单击创建

接下来,创建一个服务帐户密钥:

  1. 单击您创建的服务帐户的电子邮件地址。
  2. 单击Keys选项卡。
  3. 添加键下拉列表中,选择创建新的密钥
  4. 点击创建

您的新公钥/私钥对已生成并下载到您的机器上;它是私钥的唯一副本。您有责任安全地存储它。如果您丢失了这个密钥对,您将需要生成一个新的。

Sie können jederzeit zu 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 generieren. Weitere Informationen zu Dienstkonto-Anmeldedaten in der API Consolefinden Sie unter Dienstkonten in der API Console-Hilfedatei.

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 zugreifen kann. Ihre Anwendung benötigt sie, um autorisierte API-Aufrufe auszuführen.

Die domainweite Autorisierung an das Dienstkonto delegieren

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

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

  1. Gehen Sie in der Admin-Konsole Ihrer Google Workspace-Domain zu Hauptmenü > Sicherheit > Zugriff und Datensteuerung & API-Steuerung.
  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 in das Feld OAuth-Bereiche (durch Kommas getrennt) die Liste der Bereiche ein, auf die Ihre Anwendung Zugriff erhalten soll. Wenn Ihre Anwendung beispielsweise domainweiten 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 jetzt befugt, API-Aufrufe als Nutzer in Ihrer Domain auszuführen (um Nutzer imitieren zu können). Wenn Sie sich auf autorisierte API-Aufrufe vorbereiten, geben Sie den Nutzer an, dessen Identität übernommen wird.

Autorisierten API-Aufruf vorbereiten

Java

Nachdem du die Client-E-Mail-Adresse und den privaten Schlüssel von API Consoleerhalten hast, kannst du mit der Google APIs-Clientbibliothek für Java ein GoogleCredential-Objekt aus den Anmeldedaten des Dienstkontos und den Bereichen erstellen, auf die deine 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 für Anwendungen verwenden. Das vereinfacht den Prozess.

Domainweite Bevollmächtigte 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");

Mit dem Objekt GoogleCredential können Sie Google APIs in Ihrer Anwendung aufrufen.

Python

Nachdem du die Client-E-Mail-Adresse und den privaten Schlüssel von API Consoleerhalten hast, kannst du mit der Google APIs-Clientbibliothek für Python die folgenden Schritte ausführen:

  1. Erstellen Sie ein Credentials-Objekt aus den Anmeldedaten des Dienstkontos und der Bereiche, 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 für Anwendungen verwenden. Das vereinfacht den Prozess.

  2. Domainweite Bevollmächtigte delegieren

    Wenn Sie 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')

Rufen Sie mit dem Anmeldedatenobjekt Google APIs in Ihrer Anwendung auf.

HTTP/REST

Nachdem du die Client-ID und den privaten Schlüssel aus API Consoleerhalten hast, muss deine Anwendung die folgenden Schritte ausführen:

  1. Erstellen Sie ein JSON Web Token (JWT, ausgesprochen, &jot&jot); das einen Header, einen Anspruchssatz und eine Signatur enthält.
  2. Fordern Sie ein Zugriffstoken vom Google OAuth 2.0-Autorisierungsserver an.
  3. Verarbeiten Sie 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, sind Ihr JWT und die Tokenanfrage möglicherweise nicht korrekt formatiert oder das Dienstkonto ist möglicherweise nicht berechtigt, auf die angeforderten Bereiche zuzugreifen.

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

Ihre Serveranwendung verwendet dann ein JWT, um ein Token vom Google-Autorisierungsserver anzufordern. Anschließend wird das Token mit einem Google API-Endpunkt aufgerufen. Es gibt keinen Endnutzer.

Im Rest dieses Abschnitts werden die Details zum Erstellen eines JWT, zum Signieren des JWT, zum Erstellen der Zugriffstokenanfrage und zum Verarbeiten der Antwort beschrieben.

JWT erstellen

Ein JWT besteht aus drei Teilen: einem Header, einem Anspruchssatz und einer Signatur. Header und Anspruchsgruppe sind JSON-Objekte. Diese JSON-Objekte werden in UTF-8-Byte serialisiert und dann mit der Base64url-Codierung codiert. Diese Codierung bietet Belastbarkeit gegenüber Codierungsänderungen aufgrund wiederholter Codierungsvorgänge. Header, Anspruchssatz und 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 bilden

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. Mit der Einführung weiterer Algorithmen und Formate ändert sich dieser Header entsprechend.

Dienstkonten nutzen den RSA-SHA-256-Algorithmus und das JWT-Tokenformat. Daher sieht die JSON-Darstellung des Headers so aus:

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

Die Base64url-Darstellung sieht so aus:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
JWT-Anforderungssatz bilden

Der JWT-Anspruchssatz enthält Informationen zum JWT, einschließlich der angeforderten Berechtigungen (Umfang), dem Ziel des Tokens, dem Aussteller, der Ausstellung des Tokens und der Lebensdauer des Tokens. Die meisten Felder sind Pflichtfelder. Wie der JWT-Header ist auch der JWT-Anforderungssatz ein JSON-Objekt und wird in der Berechnung der Signatur verwendet.

Erforderliche Ansprüche

Die erforderlichen Anforderungen im JWT-Anspruchssatz sind unten aufgeführt. Sie können in beliebiger Reihenfolge im Anspruchssatz erscheinen.

Name Beschreibung
iss Die E-Mail-Adresse des Dienstkontos.
scope Eine Liste mit durch Leerzeichen voneinander getrennten Berechtigungen, die von der Anwendung angefordert werden.
aud Eine Beschreibung des beabsichtigten Ziels der Assertion. Wenn Sie eine Zugriffstokenanfrage senden, ist dieser Wert immer https://oauth2.googleapis.com/token.
exp Die Ablaufzeit der Assertion, angegeben in Sekunden seit dem 1. Januar 1970 um 00:00:00 Uhr (UTC). Der Wert darf innerhalb einer Stunde nach der ausgestellten Zeit maximal eine Stunde betragen.
iat Der Zeitpunkt, zu dem die Assertion ausgeführt wurde, angegeben in Sekunden seit 1. Januar 1970, 00:00:00 Uhr (UTC).

Hier sehen Sie die JSON-Darstellung der erforderlichen Felder in einem JWT-Anspruchssatz:

{
  "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 verwenden, um im Namen eines bestimmten Nutzers in einer Organisation zu handeln. Die Berechtigung zum Identitätswechsel muss gewährt werden, bevor eine Anwendung einen Nutzer imitieren kann und normalerweise von einem Super Admin verwaltet wird. Weitere Informationen finden Sie unter API-Zugriff mit domainweiter Delegierung steuern.

Wenn Sie ein Zugriffstoken abrufen möchten, das einer Anwendung delegierten Zugriff auf eine Ressource gewährt, geben Sie die E-Mail-Adresse des Nutzers in der JWT-Anforderung an, 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, die das Feld sub enthält, ein Fehler zurückgegeben.

Unten sehen Sie 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 der JWT-Anforderungssatz in UTF-8 serialisiert und mit Base64url-sicher codiert sein. Hier sehen Sie eine JSON-Darstellung eines JWT-Anspruchs:

{
  "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 die Mechanismen zur Generierung 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 des Google OAuth 2.0-Autorisierungsservers ist SHA-256-Hash-Algorithmus. Dies wird im Feld alg im JWT-Header als RS256 ausgedrückt.

Signiere die UTF-8-Darstellung der Eingabe mit SHA256withRSA (auch bekannt als RSASSA-PKCS1-V1_5-SIGN mit der SHA-256-Hashfunktion). Verwende dazu den privaten Schlüssel aus dem Google API Console. Die Ausgabe ist ein Byte-Array.

Die Signatur muss dann mit Base64url codiert sein. Header, Anspruchssatz und Signatur werden mit einem Punkt (.) verkettet. Das Ergebnis ist das JWT. Sie sollte folgendermaßen aussehen (Zeilenumbrüche zum besseren Verständnis hinzugefügt):

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

Nachfolgend sehen Sie ein Beispiel eines JWT vor der Base64url-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]

Nachfolgend sehen Sie ein Beispiel für ein JWT, das signiert wurde und übertragen werden kann:

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

Zugriffstoken-Anfrage erstellen

Nachdem das signierte JWT generiert wurde, kann es von einer Anwendung verwendet werden, um ein Zugriffstoken anzufordern. Diese Zugriffstoken-Anfrage ist eine HTTPS-POST-Anfrage und der Text ist URL-codiert. Die URL ist unten dargestellt:

https://oauth2.googleapis.com/token

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

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

Im Folgenden ist ein Roh-Dump der HTTPS-POST-Anfrage aufgeführt, 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 Zugriffstoken-Anfrage korrekt formatiert sind und das Dienstkonto die Berechtigung zum Ausführen dieses Vorgangs hat, enthält die JSON-Antwort vom Autorisierungsserver 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 Dauerzeitraums wiederverwendet werden, der durch den Wert expires_in angegeben wird.

Google APIs aufrufen

Java

Führen Sie die folgenden Schritte aus, um die Google APIs mithilfe des Objekts GoogleCredential aufzurufen:

  1. Erstellen Sie mit dem GoogleCredential-Objekt ein Dienstobjekt für die API, die Sie aufrufen möchten. Beispiel:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Anfragen an den API-Dienst über die Schnittstelle, die vom Dienstobjekt bereitgestellt wird So rufen 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 dazu die folgenden Schritte aus, um das autorisierte Objekt Credentials zu verwenden:

  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. Anfragen an den API-Dienst über die Schnittstelle, die vom Dienstobjekt bereitgestellt wird So rufen 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 abgerufen hat, können Sie das Token verwenden, um eine Anfrage an eine Google API im Namen eines bestimmten Dienstkontos oder Nutzerkontos zu senden, sofern der von der API erforderliche Zugriffsbereich(e) gewährt wurde. Füge dazu das Zugriffstoken in eine Anfrage an die API ein. Füge dazu entweder den access_token-Abfrageparameter oder den Authorization-HTTP-Header-Wert Bearer ein. Der HTTP-Header wird nach Möglichkeit bevorzugt, da Abfragestrings in der Regel in Serverlogs sichtbar sind. In den meisten Fällen können Sie eine Clientbibliothek verwenden, um Aufrufe an Google APIs einzurichten, z. B. beim Aufruf der Drive Files API.

Du kannst alle Google APIs ausprobieren und dir ihre Bereiche im OAuth 2.0 Playground ansehen.

Beispiele für HTTP GET

Ein Aufruf des Endpunkts drive.files (Drive Files API) über den HTTP-Header Authorization: Bearer sieht so aus. Sie müssen Ihr eigenes Zugriffstoken angeben:

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

Im Folgenden finden Sie einen 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

Du kannst diese Befehle mit der curl-Befehlszeile testen. Beispiel für die HTTP-Header-Option (bevorzugt):

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

Alternativ haben Sie die Möglichkeit, die Parameteroption für Abfragestrings auszuwählen:

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

Wann Zugriffstokens ablaufen

Vom Google OAuth 2.0-Autorisierungsserver ausgestellte Zugriffstokens laufen nach der vom expires_in-Wert bereitgestellten Dauer ab. Wenn ein Zugriffstoken abläuft, sollte die Anwendung ein weiteres JWT generieren, es signieren und ein weiteres Zugriffstoken anfordern.

JWT-Fehlercodes

Feld error Feld error_description Bedeutung Klären
unauthorized_client Unauthorized client or scope in request. Wenn Sie versuchen, die domainweite Delegierung zu verwenden, ist das Dienstkonto in der Admin-Konsole der Nutzerdomain nicht autorisiert.

Sorgen Sie dafür, dass das Dienstkonto in der Admin-Konsole auf der Seite Domainweite Delegierung für den Nutzer im Feld sub autorisiert ist (Feld).

In der Regel dauert es einige Minuten. Es kann 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 statt mit der Client-ID (numerisch) in der Admin-Konsole autorisiert. Entfernen Sie den Client in der Admin-Konsole auf der Seite Domainweite Delegierung und fügen Sie ihn mit der numerischen ID noch einmal hinzu.
access_denied (beliebiger Wert) Wenn Sie die domainweite Delegierung verwenden, werden mindestens ein angeforderter Bereich in der Admin-Konsole autorisiert.

Prüfen Sie, ob das Dienstkonto auf der Seite Domainweite Delegierung der Admin-Konsole für den Nutzer im sub-Anspruch (Feld) autorisiert ist und alle Bereiche enthält, die Sie in der scope-Anforderung Ihres JWT anfordern.

In der Regel dauert es einige Minuten. Es kann 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 sub-Anspruch (Feld) 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 örtliche Systemzeit nicht korrekt ist. Das kann auch passieren, wenn der Wert von exp mehr als 65 Minuten nach dem Wert iat liegt oder der Wert von exp niedriger als der Wert iat ist.

Prüfen Sie, ob die Uhr auf dem System, auf dem das JWT generiert wird, korrekt ist. Synchronisieren Sie bei Bedarf Ihre Zeit mit Google NTP.

invalid_grant Invalid JWT Signature.

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

Alternativ ist die JWT-Assertion möglicherweise falsch codiert. Sie muss Base64-codiert sein und darf keine Zeilenumbrüche oder Abstandszeichen enthalten.

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

Verwenden Sie eine von Google bereitgestellte OAuth-Bibliothek, um zu prüfen, ob das JWT korrekt generiert wird.

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

Achten Sie darauf, dass die scope-Anforderung (Feld) des JWT ausgefüllt ist. Vergleichen Sie die Bereiche, die sie enthalten, mit den dokumentierten Bereichen für die zu verwendenden APIs, um sicherzustellen, dass es keine Fehler oder Tippfehler gibt.

Die Liste der Bereiche im Anspruch scope muss durch Leerzeichen getrennt werden, nicht durch Kommas.

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

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

Ergänzung: Dienstkontoautorisierung ohne OAuth

Bei einigen Google APIs können Sie autorisierte API-Aufrufe mit einem signierten JWT direkt als Inhabertoken statt eines OAuth 2.0-Zugriffstokens ausführen. Wenn es möglich ist, müssen Sie keine Netzwerkanfrage an den Autorisierungsserver von Google senden, bevor Sie einen API-Aufruf starten.

Wenn die API, die Sie aufrufen möchten, eine Dienstdefinition im Google APIs-GitHub-Repository hat, können Sie autorisierte API-Aufrufe mit einem JWT anstelle eines Zugriffstokens ausführen. Gehe dazu folgendermaßen vor:

  1. Erstellen Sie ein Dienstkonto wie oben beschrieben. Bewahren Sie die JSON-Datei auf, die Sie beim Erstellen des Kontos erhalten.
  2. Erstellen Sie mit einer beliebigen JWT-Standardbibliothek, z. B. einer unter jwt.io, ein JWT mit Header und 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. Diesen Wert finden Sie im Feld private_key_id der JSON-Datei Ihres Dienstkontos.
    • Geben Sie für die Felder iss und sub die E-Mail-Adresse des Dienstkontos an. Diesen Wert finden Sie 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 an, die genau 3.600 Sekunden später liegen soll, wenn das JWT abläuft.

Signieren Sie das JWT mit RSA-256 unter Verwendung des privaten Schlüssels in der JSON-Datei Ihres Dienstkontos.

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