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, das zu Ihrer Anwendung und nicht zu einem einzelnen Endnutzer gehört. Ihre Anwendung ruft Google APIs im Namen des Dienstkontos auf, sodass Nutzer nicht direkt beteiligt sind. Dieses Szenario wird manchmal als „OAuth mit zwei Schritten“ oder „2LO“ bezeichnet. Der zugehörige Begriff „dreibeiniges OAuth“ bezieht sich auf Szenarien, in denen Ihre Anwendung Google APIs im Namen von Endnutzern aufruft und in denen manchmal die Einwilligung des Nutzers erforderlich ist.
Normalerweise verwendet eine Anwendung ein Dienstkonto, wenn sie Google APIs verwendet, um mit eigenen Daten statt mit den Daten eines Nutzers zu arbeiten. Eine Anwendung, die Google Cloud Datastore für die Datenspeicherung verwendet, würde beispielsweise ein Dienstkonto verwenden, um ihre Aufrufe der Google Cloud Datastore API zu authentifizieren.
Google Workspace-Domainadministratoren können Dienstkonten auch domainweite Berechtigungen zum Zugriff auf Nutzerdaten im Namen von Nutzern in der Domain gewähren.
In diesem Dokument wird beschrieben, wie eine Anwendung den OAuth 2.0-Ablauf von Server zu Server mithilfe einer Google APIs-Clientbibliothek (empfohlen) oder HTTP abschließen kann.
Übersicht
Wenn Sie Server-zu-Server-Interaktionen unterstützen möchten, erstellen Sie zuerst ein Dienstkonto für Ihr Projekt in der API Console. Wenn Sie auf Nutzerdaten für Nutzer in Ihrem Google Workspace-Konto zugreifen möchten, delegieren Sie dem Dienstkonto domainweiten Zugriff.
Anschließend bereitet Ihre Anwendung autorisierte API-Aufrufe vor, indem sie mit den Anmeldedaten des Dienstkontos ein Zugriffstoken vom OAuth 2.0-Autorisierungsserver anfordert.
Schließlich kann Ihre Anwendung das Zugriffstoken verwenden, um Google APIs aufzurufen.
Dienstkonto erstellen
Die Anmeldedaten eines Dienstkontos umfassen eine eindeutige generierte E-Mail-Adresse und mindestens ein öffentliches/privates Schlüsselpaar. Wenn die domainweite Delegation aktiviert ist, ist auch eine Client-ID Teil der Anmeldedaten des Dienstkontos.
Wenn Ihre Anwendung in der Google App Engine ausgeführt wird, wird beim Erstellen des Projekts automatisch ein Dienstkonto eingerichtet.
Wenn Ihre Anwendung in der Google Compute Engine ausgeführt wird, wird beim Erstellen des Projekts auch automatisch ein Dienstkonto eingerichtet. Sie müssen jedoch die Bereiche angeben, auf die Ihre Anwendung zugreifen muss, wenn Sie eine Google Compute Engine-Instanz erstellen. Weitere Informationen finden Sie unter Instanz für die Verwendung von Dienstkonten vorbereiten.
Wenn Ihre Anwendung nicht in der Google App Engine oder der Google Compute Engine ausgeführt wird, müssen Sie diese Anmeldedaten in der Google API Consoleabrufen. So generieren Sie Anmeldedaten für ein Dienstkonto oder rufen Sie die bereits generierten öffentlichen Anmeldedaten auf:
首先,创建一个服务帐户:
- 打开 Service accounts page。
- If prompted, select a project, or create a new one.
- 单击 创建服务帐户。
- 在Service account details下,键入服务帐户的名称、ID 和描述,然后点击Create and continue 。
- 可选:在Grant this service account access to project下,选择要授予服务帐户的 IAM 角色。
- 单击继续。
- 可选:在Grant users access to this service account下,添加允许使用和管理服务帐户的用户或组。
- 单击完成。
接下来,创建一个服务帐户密钥:
- 单击您创建的服务帐户的电子邮件地址。
- 单击密钥选项卡。
- 在添加密钥下拉列表中,选择创建新密钥。
- 单击创建。
您的新公钥/私钥对已生成并下载到您的机器上;它作为私钥的唯一副本。您有责任安全地存储它。如果您丢失了这个密钥对,您将需要生成一个新的。
Sie können jederzeit zu API Console zurückkehren, um die E-Mail-Adresse, die Fingerabdrücke öffentlicher Schlüssel und andere Informationen aufzurufen oder zusätzliche Paare aus öffentlichem/privatem Schlüssel zu generieren. Weitere Informationen zu den Anmeldedaten für Dienstkonten in der API Consolefinden Sie in der Hilfe unter Dienstkonten. API Console
Notieren Sie sich die E-Mail-Adresse des Dienstkontos und speichern Sie die Datei mit dem privaten Schlüssel des Dienstkontos an einem Ort, auf den Ihre Anwendung zugreifen kann. Ihre Anwendung benötigt sie, um autorisierte API-Aufrufe auszuführen.
Domainweite Befugnisse an das Dienstkonto delegieren
Über ein Google Workspace-Konto kann ein Workspace-Administrator der Organisation eine Anwendung dazu autorisieren, im Namen von Nutzern in der Google Workspace-Domain auf Workspace-Nutzerdaten zuzugreifen. Beispielsweise nutzt eine Anwendung, die die Google Calendar API zum Hinzufügen von Ereignissen zu den Kalendern aller Nutzer in einer Google Workspace-Domain verwendet, ein Dienstkonto, 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 als „Übertragen domainweiter Befugnisse“ an ein Dienstkonto bezeichnet.
Wenn ein Super Admin der Google Workspace-Domain einem Dienstkonto domainweite Berechtigungen zuweisen möchte, muss er die folgenden Schritte ausführen:
- Klicken Sie in der Admin-Konsole Ihrer Google Workspace-Domain auf das Hauptmenü > „Sicherheit“ > „Zugriffs- und Datenkontrolle“ > „API-Steuerung“.
- Wählen Sie im Bereich Domainweite Delegierung die Option Domainweite Delegierung verwalten aus.
- Klicken Sie auf Neu hinzufügen.
- Geben Sie im Feld Client-ID die Client-ID des Dienstkontos ein. Die Client-ID Ihres Dienstkontos finden Sie in der Service accounts page.
- Geben Sie im Feld OAuth-Bereiche (durch Kommas getrennt) die Liste der Bereiche ein, auf die Ihre Anwendung Zugriff haben soll. Wenn Ihre Anwendung beispielsweise domainweit vollständigen Zugriff auf die Google Drive API und die Google Calendar API benötigt, geben Sie Folgendes ein: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
- Klicken Sie auf Autorisieren.
Ihre Anwendung ist jetzt berechtigt, API-Aufrufe als Nutzer in Ihrer Workspace-Domain auszuführen, um Nutzer zu „impersonieren“. Wenn Sie diese delegierten API-Aufrufe vorbereiten, geben Sie den Nutzer, für den Sie sich ausgeben möchten, explizit an.
Vorbereiten eines delegierten API-Aufrufs
Java
Nachdem Sie die E-Mail-Adresse des Clients und den privaten Schlüssel aus der API Consoleabgerufen haben, erstellen Sie mit der Google APIs Client Library for Java ein GoogleCredential
-Objekt aus den Anmeldedaten des Dienstkontos und den Bereichen, auf die Ihre Anwendung zugreifen muss. 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 in der Google Cloud-Plattform entwickeln, können Sie stattdessen die Standardanmeldedaten für Anwendungen verwenden. Dies vereinfacht den Vorgang.
Domainweite Befugnisse delegieren
Wenn Sie 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 GoogleCredential
-Objekts an. Beispiel:
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN)) .createDelegated("workspace-user@example.com");
Im obigen Code wird das GoogleCredential
-Objekt verwendet, um die createDelegated()
-Methode aufzurufen. Das Argument für die createDelegated()
-Methode muss ein Nutzer sein, der zu Ihrem Workspace-Konto gehört. Der Code, der die Anfrage stellt, verwendet diese Anmeldedaten, um Google APIs mit Ihrem Dienstkonto aufzurufen.
Python
Nachdem Sie die E-Mail-Adresse des Kunden und den privaten Schlüssel von der API Consoleabgerufen haben, führen Sie mit der Google APIs-Clientbibliothek für Python die folgenden Schritte aus:
- 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 in der Google Cloud-Plattform entwickeln, können Sie stattdessen die Standardanmeldedaten für Anwendungen verwenden. Dies vereinfacht den Vorgang.
- Domainweite Befugnisse delegieren
Wenn Sie domainweiten Zugriff auf das Dienstkonto delegiert haben und die Identität eines Nutzerkontos übernehmen möchten, verwenden Sie die
with_subject
-Methode eines vorhandenenServiceAccountCredentials
-Objekts. Beispiel:delegated_credentials = credentials.with_subject('user@example.org')
Verwenden Sie das Anmeldedatenobjekt, um Google APIs in Ihrer Anwendung aufzurufen.
HTTP/REST
Nachdem Sie die Client-ID und den privaten Schlüssel von der API Consoleerhalten haben, müssen Sie in Ihrer Anwendung die folgenden Schritte ausführen:
- Erstellen Sie ein JSON Web Token (JWT, ausgesprochen „jot“), das einen Header, einen Anforderungssatz und eine Signatur enthält.
- Fordern Sie ein Zugriffstoken vom Google OAuth 2.0 Authorization Server an.
- JSON-Antwort des Autorisierungsservers verarbeiten
In den folgenden Abschnitten wird beschrieben, wie Sie diese Schritte ausführen.
Wenn die Antwort ein Zugriffstoken enthält, können Sie es zum Aufrufen einer Google API verwenden. Wenn die Antwort kein Zugriffstoken enthält, sind JWT und Tokenanfrage möglicherweise nicht richtig formatiert oder das Dienstkonto hat keine Berechtigung zum Zugriff auf die angeforderten Bereiche.
Wenn das Zugriffstoken abläuft, generiert Ihre Anwendung ein weiteres JWT, signiert es und fordert ein weiteres Zugriffstoken an.
Im restlichen Teil dieses Abschnitts werden die Details zum Erstellen, Signieren, Erstellen der Zugriffstokenanfrage und zum Umgang mit 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 Base64url-Codierung codiert. Diese Codierung bietet Schutz vor Codierungsänderungen aufgrund wiederholter Codierungsvorgänge. Der Header, der Anspruchssatz und die Signatur werden mit einem Punkt (.
) verkettet.
Ein JWT besteht aus folgenden Elementen:
{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 drei Feldern, die den Signaturalgorithmus, das Format der Bestätigung und die [Schlüssel-ID des Dienstkontoschlüssels](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) angeben, mit dem das JWT signiert wurde. Algorithmus und Format sind obligatorisch und jedes Feld hat nur einen Wert. Wenn zusätzliche Algorithmen und Formate eingeführt werden, ändert sich dieser Header entsprechend. Die Schlüssel-ID ist optional. Wenn eine falsche Schlüssel-ID angegeben wird, versucht GCP, alle mit dem Dienstkonto verknüpften Schlüssel zu verwenden, um das Token zu überprüfen. Wenn kein gültiger Schlüssel gefunden wird, wird das Token abgelehnt. Google behält sich das Recht vor, Token mit falschen Schlüssel-IDs in Zukunft abzulehnen.
Dienstkonten basieren auf dem RSA SHA-256-Algorithmus und dem JWT-Tokenformat. Die JSON-Darstellung des Headers sieht so aus:
{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}
Die Base64url-Darstellung lautet:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
JWT-Anforderungssatz bilden
Der JWT-Anspruchssatz enthält Informationen zum JWT, einschließlich der angeforderten Berechtigungen (Bereiche), des Ziels des Tokens, des Ausstellers, des Zeitpunkts 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, das zur Berechnung der Signatur verwendet wird.
Erforderliche Ansprüche
Die erforderlichen Ansprüche im JWT-Anforderungssatz sind unten aufgeführt. Sie können in beliebiger Reihenfolge im Anforderungssatz angezeigt werden.
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 Behauptung. Bei einer Zugriffstokenanfrage ist dieser Wert immer https://oauth2.googleapis.com/token . |
exp |
Die Ablaufzeit der Bestätigung, angegeben als Sekunden seit 00:00:00 UTC, 1. Januar 1970. Dieser Wert darf maximal eine Stunde nach der Ausstellung liegen. |
iat |
Die Uhrzeit, zu der die Behauptung abgegeben wurde, angegeben in Sekunden seit 00:00:00 UTC, 1. Januar 1970. |
Im Folgenden finden Sie eine JSON-Darstellung der erforderlichen Felder 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 }
Weitere Ansprüche
In einigen Fällen kann eine Anwendung die domainweite Delegierung verwenden, um im Namen eines bestimmten Nutzers in einer Organisation zu handeln. Die Berechtigung für diese Art der Identitätsdiebstahl muss gewährt werden, bevor eine Anwendung sich als Nutzer ausgeben kann. Sie wird in der Regel von einem Super Admin verwaltet. Weitere Informationen finden Sie unter Zugriff auf die API mit domainweiter Delegierung verwalten.
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 den JWT-Claim ein, der als Wert für das 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, sich als Nutzer auszugeben, enthält die Antwort auf eine Zugriffstokenanfrage mit dem Feld sub
den Fehler.
Unten sehen Sie ein Beispiel für einen JWT-Anforderungssatz, der das Feld sub
enthält:
{ "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 serialisiert und base64url-sicher codiert werden. Unten sehen Sie 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 Web Signature (JWS)-Spezifikation regelt, wie die Signatur für das JWT erzeugt wird. 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 bei der Berechnung der Signatur verwendet werden. Der einzige vom Google OAuth 2.0-Autorisierungsserver unterstützte Signaturalgorithmus ist RSA mit dem SHA-256-Hash-Algorithmus. Dies wird als RS256
im Feld alg
im JWT-Header ausgedrückt.
Signieren Sie die UTF-8-Darstellung der Eingabe mit SHA256withRSA (auch bekannt als RSASSA-PKCS1-V1_5-SIGN mit der SHA-256-Hash-Funktion) mit dem privaten Schlüssel, der aus der Google API Consoleabgerufen wurde. Die Ausgabe ist ein Byte-Array.
Die Signatur muss dann Base64url-codiert sein. Der Header, der Anspruchssatz und die Signatur werden mit einem Punkt (.
) verkettet. Das Ergebnis ist das JWT. Sie sollte so aussehen (Zeilenumbrüche zur Verdeutlichung hinzugefügt):
{Base64url encoded header}. {Base64url encoded claim set}. {Base64url encoded signature}
Unten sehen Sie ein Beispiel für ein 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]
Unten sehen Sie ein Beispiel für ein signiertes JWT, das zur Übertragung bereit ist:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ
Zugriffstoken anfordern
Nachdem das signierte JWT generiert wurde, kann eine Anwendung damit ein Zugriffstoken anfordern.
Diese Zugriffstokenanfrage ist eine HTTPS-POST
-Anfrage und der Textkörper ist URL-codiert. Die URL ist unten zu sehen:
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 werden muss:
urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion |
Das JWT, einschließlich Signatur. |
Unten findest du einen Rohdump 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
Unten ist dieselbe Anfrage mit curl
zu sehen:
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
Umgang mit der Antwort
Wenn die JWT- und Zugriffstokenanfrage korrekt formatiert ist und das Dienstkonto die Berechtigung zum Ausführen des Vorgangs hat, enthält die JSON-Antwort des Autorisierungsservers ein Zugriffstoken. Hier ist ein Beispiel für eine Antwort:
{ "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "scope": "https://www.googleapis.com/auth/prediction" "token_type": "Bearer", "expires_in": 3600 }
Zugriffstokens können während des durch den Wert expires_in
angegebenen Zeitfensters wiederverwendet werden.
Google APIs aufrufen
Java
Führen Sie die folgenden Schritte aus, um Google APIs mit dem GoogleCredential
-Objekt aufzurufen:
- Erstellen Sie ein Dienstobjekt für die API, die Sie mit dem
GoogleCredential
-Objekt aufrufen möchten. Beispiel:SQLAdmin sqladmin = new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
- Stellen Sie Anfragen an den API-Dienst über die vom Dienstobjekt bereitgestellte Benutzeroberfläche.
So listen Sie beispielsweise die Instanzen von Cloud SQL-Datenbanken im Projekt „exciting-example-123“ auf:
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
Python
Verwende das autorisierte Credentials
-Objekt, um Google APIs aufzurufen. Gehe dazu so vor:
- Erstellen Sie ein Dienstobjekt für die API, die Sie aufrufen möchten. Sie erstellen ein Dienstobjekt, indem Sie die Funktion
build
mit dem Namen und der Version der API und dem autorisiertenCredentials
-Objekt aufrufen. So rufen Sie beispielsweise Version 1beta3 der Cloud SQL Admin API auf:import googleapiclient.discovery sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
- Stellen Sie Anfragen an den API-Dienst über die vom Dienstobjekt bereitgestellte Benutzeroberfläche.
So listen Sie beispielsweise die Instanzen von Cloud SQL-Datenbanken im Projekt „exciting-example-123“ auf:
response = sqladmin.instances().list(project='exciting-example-123').execute()
HTTP/REST
Nachdem Ihre Anwendung ein Zugriffstoken erhalten hat, können Sie mit dem Token im Namen eines bestimmten Dienst- oder Nutzerkontos eine Google API aufrufen, sofern die von der API erforderlichen Zugriffsbereiche gewährt wurden. Dazu fügen Sie das Zugriffstoken in eine Anfrage an die API ein, indem Sie entweder einen access_token
-Abfrageparameter oder einen Authorization
-HTTP-Header-Bearer
-Wert angeben. Wenn möglich, ist der HTTP-Header vorzuziehen, da Suchstrings in Serverprotokollen in der Regel sichtbar sind. In den meisten Fällen können Sie mit einer Clientbibliothek Aufrufe von Google APIs einrichten, z. B. beim Aufrufen der Drive Files API.
Im OAuth 2.0 Playground können Sie alle Google APIs ausprobieren und sich ihre Bereiche ansehen.
Beispiele für HTTP-GET
Ein Aufruf des Endpunkts
drive.files
(Drive Files API) mit dem HTTP-Header Authorization: Bearer
könnte so aussehen: Sie müssen Ihr eigenes Zugriffstoken angeben:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Hier ist ein Aufruf derselben 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 Befehlszeilenanwendung curl
testen. Hier ein Beispiel, in dem die HTTP-Header-Option verwendet wird (bevorzugt):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
Alternativ können Sie auch die Option „Abfragestringparameter“ verwenden:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Ablauf von Zugriffstokens
Vom Google OAuth 2.0-Autorisierungsserver ausgestellte Zugriffstokens laufen nach der vom Wert expires_in
angegebenen 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 | Lösung |
---|---|---|---|
unauthorized_client |
Unauthorized client or scope in request. |
Wenn Sie versuchen, die domainweite Delegation zu verwenden, ist das Dienstkonto in der Admin-Konsole der Domain des Nutzers nicht autorisiert. |
Achten Sie darauf, dass das Dienstkonto auf der Seite
Domainweite Delegation der Admin-Konsole für den Nutzer im Anspruch ( Normalerweise dauert es nur wenige Minuten, es kann aber auch bis zu 24 Stunden dauern, bis die Autorisierung für alle Nutzer in Ihrem Google-Konto übernommen 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 in der Admin-Konsole mit der E-Mail-Adresse des Kunden und nicht mit der Client-ID (numerisch) autorisiert. | Entfernen Sie den Client auf der Seite Domainweite Delegierung in der Admin-Konsole und fügen Sie ihn mit der numerischen ID wieder hinzu. |
access_denied |
(beliebiger Wert) | Wenn Sie die domainweite Delegation verwenden, sind mindestens eine oder mehrere der angeforderten Bereiche in der Admin-Konsole nicht autorisiert. |
Achten Sie darauf, dass das Dienstkonto auf der Seite
Domainweite Delegierung der Admin-Konsole für den Nutzer im Anspruch ( Normalerweise dauert es nur wenige Minuten, es kann aber auch bis zu 24 Stunden dauern, bis die Autorisierung für alle Nutzer in Ihrem Google-Konto übernommen wird. |
admin_policy_enforced |
(beliebiger Wert) | Das Google-Konto kann aufgrund der Richtlinien des Google Workspace-Administrators einen oder mehrere der angeforderten Bereiche nicht autorisieren. |
Weitere Informationen dazu, wie ein Administrator den Zugriff auf alle oder vertrauliche und eingeschränkte Bereiche einschränken kann, bis der Zugriff Ihrer OAuth-Client-ID ausdrücklich gewährt wird, finden Sie im Hilfeartikel Zugriff externer und interner Apps auf Google Workspace-Daten verwalten. |
invalid_client |
(beliebiger Wert) |
Der OAuth-Client oder das JWT-Token ist ungültig oder falsch konfiguriert. Weitere Informationen finden Sie in der Fehlerbeschreibung. |
Prüfe, ob das JWT-Token gültig ist und die richtigen Ansprüche enthält. Prüfen Sie, ob der OAuth-Client und das Dienstkonto richtig konfiguriert sind und ob Sie die richtige E-Mail-Adresse verwenden. Prüfe, ob das JWT-Token korrekt ist und für die Client-ID in der Anfrage ausgestellt wurde. |
invalid_grant |
Not a valid email. |
Der Nutzer ist nicht vorhanden. | Prüfen Sie, ob die E-Mail-Adresse im Feld sub korrekt ist. |
invalid_grant |
|
In der Regel bedeutet das, dass die lokale Systemzeit nicht korrekt ist. Das kann auch passieren, wenn der exp -Wert mehr als 65 Minuten in der Zukunft liegt oder der exp -Wert niedriger als der iat -Wert ist.iat |
Achten Sie darauf, dass die Uhr auf dem System, auf dem das JWT generiert wird, richtig eingestellt ist. Synchronisieren Sie die Uhrzeit bei Bedarf mit dem Google NTP. |
invalid_grant |
Invalid JWT Signature. |
Die JWT-Bestätigung ist mit einem privaten Schlüssel signiert, der nicht mit dem Dienstkonto verknüpft ist, das über die E-Mail-Adresse des Clients identifiziert wird, oder der verwendete Schlüssel wurde gelöscht, deaktiviert oder ist abgelaufen. Alternativ kann die JWT-Assertion falsch codiert sein. Sie muss Base64-codiert sein, ohne Zeilenumbrüche oder Füllzeichen. |
Entschlüsseln Sie die JWT-Anforderungsgruppe und prüfen Sie, ob der Schlüssel, mit dem die Behauptung signiert wurde, mit dem Dienstkonto verknüpft ist. Verwenden Sie eine von Google bereitgestellte OAuth-Bibliothek, um sicherzustellen, dass 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 existiert nicht (d.h. ist ungültig). |
Prüfen Sie, ob der Anspruch (das Feld) Die Liste der Bereiche im |
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, die zum Signieren der Bestätigung verwendet wurde. |
org_internal |
This client is restricted to users within its organization. |
Die OAuth-Client-ID in der Anfrage ist Teil eines Projekts, das den Zugriff auf Google-Konten in einer bestimmten Google Cloud-Organisation einschränkt. |
Verwenden Sie ein Dienstkonto der Organisation für die Authentifizierung. Bestätigen Sie die Konfiguration des Nutzertyps für Ihre OAuth-Anwendung. |
Anhang: Autorisierung über ein Dienstkonto ohne OAuth
Bei einigen Google APIs können Sie autorisierte API-Aufrufe mit einem signierten JWT direkt als Inhabertoken anstelle eines OAuth 2.0-Zugriffstokens ausführen. So können Sie vermeiden, dass eine Netzwerkanfrage an den Autorisierungsserver von Google gesendet wird, bevor Sie einen API-Aufruf vornehmen.
Wenn für die API, die Sie aufrufen möchten, eine Dienstdefinition im GitHub-Repository von Google APIs veröffentlicht wurde, können Sie autorisierte API-Aufrufe mit einem JWT anstelle eines Zugriffstokens ausführen. Anleitung:
- Erstellen Sie ein Dienstkonto wie oben beschrieben. Bewahren Sie die JSON-Datei auf, die Sie beim Erstellen des Kontos erhalten.
- Erstelle mit einer beliebigen Standard-JWT-Bibliothek, z. B. einer von 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
in der Kopfzeile die ID des privaten Schlüssels Ihres Dienstkontos an. Sie finden diesen Wert im Feldprivate_key_id
der JSON-Datei Ihres Dienstkontos. - Geben Sie in den Feldern
iss
undsub
die E-Mail-Adresse Ihres Dienstkontos an. Sie finden diesen Wert im Feldclient_email
der JSON-Datei Ihres Dienstkontos. - Geben Sie für das 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 Feldexp
die Zeit an, die genau 3.600 Sekunden später eintritt, also der Zeitpunkt, zu dem das JWT abläuft.
Signieren Sie das JWT mit RSA-256 und dem privaten Schlüssel 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')
- Rufen Sie die API mit dem signierten JWT als Bearer-Token auf:
GET /v1/projects/abc/databases/123/indexes HTTP/1.1 Authorization: Bearer SIGNED_JWT Host: firestore.googleapis.com
Produktübergreifenden Kontoschutz implementieren
Sie sollten außerdem den Kontoübergreifenden Schutz implementieren, indem Sie den Kontoübergreifenden Schutzdienst von Google verwenden. Mit diesem Dienst können Sie Benachrichtigungen zu Sicherheitsereignissen abonnieren, die Ihre Anwendung über wichtige Änderungen am Nutzerkonto informieren. Je nachdem, wie Sie auf Ereignisse reagieren möchten, können Sie dann Maßnahmen ergreifen.
Beispiele für Ereignistypen, die vom geräteübergreifenden Schutzdienst von Google an Ihre App gesendet werden:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
Auf der Seite Nutzerkonten mit dem produktübergreifenden Kontoschutz schützen finden Sie weitere Informationen zur Implementierung des produktübergreifenden Kontoschutzes und eine vollständige Liste der verfügbaren Ereignisse.