System Google OAuth 2.0 obsługuje interakcję między serwerami, na przykład między aplikacją internetową a usługą Google. W tym scenariuszu potrzebujesz konta usługi, które należy do Twojej aplikacji, a nie do użytkownika końcowego. Aplikacja wywołuje interfejsy API Google w imieniu konta usługi, więc użytkownicy nie biorą bezpośrednio udziału w tym procesie. Ten scenariusz jest czasami nazywany „dwuskładnikowe uwierzytelnianie OAuth” lub „2LO”. (Powiązany termin „trzyskładnikowe uwierzytelnianie OAuth” odnosi się do sytuacji, w których aplikacja wywołuje interfejsy API Google w imieniu użytkowników i w których czasami wymagana jest zgoda użytkownika).
Więcej informacji znajdziesz w artykule Sprawdzone metody dotyczące kont usługi.
Zazwyczaj aplikacja używa konta usługi, gdy korzysta z interfejsów API Google do pracy z własnymi danymi, a nie z danymi użytkownika. Na przykład aplikacja, która używa Google Cloud Datastore do utrwalania danych, używa konta usługi do uwierzytelniania wywołań interfejsu Google Cloud Datastore API.
Administratorzy domeny Google Workspace mogą też przyznawać kontom usługi uprawnienia w całej domenie, aby uzyskiwać dostęp do danych użytkowników w domenie w ich imieniu.
W tym dokumencie opisujemy, jak aplikacja może ukończyć przepływ OAuth 2.0 w trybie serwer-serwer, korzystając z biblioteki klienta interfejsów API Google (zalecane) lub HTTP.
Przegląd
Aby obsługiwać interakcje między serwerami, najpierw utwórz konto usługi dla swojego projektu w Konsoli interfejsów API. Jeśli chcesz uzyskać dostęp do danych użytkowników na koncie Google Workspace, przekaż konto usługi dostęp w całej domenie.
Następnie aplikacja przygotowuje się do wykonywania autoryzowanych wywołań interfejsu API, używając danych logowania konta usługi do wysyłania żądań tokena dostępu do serwera autoryzacji OAuth 2.0.
Na koniec aplikacja może użyć tokena dostępu do wywoływania interfejsów API Google.
Tworzenie konta usługi
Dane logowania konta usługi obejmują wygenerowany adres e-mail, który jest unikalny, oraz co najmniej 1 parę kluczy publicznego i prywatnego. Jeśli przekazywanie dostępu w całej domenie jest włączone, identyfikator klienta jest również częścią danych logowania konta usługi.
Jeśli Twoja aplikacja działa w Google App Engine, konto usługi jest konfigurowane automatycznie podczas tworzenia projektu.
Jeśli Twoja aplikacja działa w Google Compute Engine, konto usługi jest też konfigurowane automatycznie podczas tworzenia projektu, ale podczas tworzenia instancji Google Compute Engine musisz określić zakresy, do których Twoja aplikacja potrzebuje dostępu. Więcej informacji znajdziesz w artykule Przygotowywanie instancji do korzystania z kont usługi.
Jeśli aplikacja nie działa w Google App Engine ani Google Compute Engine, musisz uzyskać te dane logowania w konsoli interfejsów API Google. Aby wygenerować dane logowania konta usługi lub wyświetlić wygenerowane już dane logowania publiczne:
Najpierw utwórz konto usługi:
- Otwórz stronę Konta usługi.
- Jeśli pojawi się monit, wybierz projekt lub utwórz nowy.
- Kliknij Utwórz konto usługi.
- W sekcji Szczegóły konta usługi wpisz nazwę, identyfikator i opis konta usługi, a potem kliknij Utwórz i kontynuuj.
- Opcjonalnie: w sekcji Przyznaj temu kontu usługi dostęp do projektu wybierz role uprawnień, które chcesz przypisać do konta usługi.
- Kliknij Dalej.
- Opcjonalnie: w sekcji Przyznaj użytkownikom dostęp do tego konta usługi dodaj użytkowników lub grupy, które mogą używać konta usługi i nim zarządzać.
- Kliknij Gotowe.
Następnie utwórz klucz konta usługi:
- Kliknij adres e-mail utworzonego konta usługi.
- Kliknij kartę Klucze.
- Na liście Dodaj klucz kliknij Utwórz nowy klucz.
- Kliknij Utwórz.
Więcej informacji znajdziesz w artykule Sprawdzone metody zarządzania kluczami konta usługi.
W dowolnym momencie możesz wrócić do Konsoli interfejsów API, aby wyświetlić adres e-mail, odciski klucza publicznego i inne informacje lub wygenerować dodatkowe pary kluczy publicznych i prywatnych. Więcej informacji o danych logowania konta usługi w Konsoli interfejsów API znajdziesz w pliku pomocy Konsoli interfejsów API w sekcji Konta usługi.
Zanotuj adres e-mail konta usługi i zapisz plik klucza prywatnego konta usługi w lokalizacji dostępnej dla aplikacji. Aplikacja potrzebuje ich do wykonywania autoryzowanych wywołań interfejsu API.
Przekazywanie kontu usługi uprawnień do całej domeny
Administrator Workspace w organizacji może autoryzować aplikację, aby uzyskiwała dostęp do danych użytkowników Workspace w imieniu użytkowników w domenie Google Workspace. Na przykład aplikacja, która używa interfejsu Google Calendar API do dodawania wydarzeń do kalendarzy wszystkich użytkowników w domenie Google Workspace, używa konta usługi, aby uzyskiwać dostęp do interfejsu Google Calendar API w imieniu użytkowników. Przyznanie kontu usługi dostępu do danych w imieniu użytkowników w domenie jest czasami określane jako „przekazywanie kontu usługi uprawnień do całej domeny”.
Aby przekazać uprawnienia w obrębie całej domeny na konto usługi, superadministrator domeny Google Workspace musi wykonać te czynności:
- W konsoli administracyjnej domeny Google Workspace otwórz Menu główne > Bezpieczeństwo > Dostęp do danych i kontrola danych > Dostęp do interfejsów API.
- W okienku Przekazywanie dostępu w całej domenie kliknij Zarządzaj przekazywaniem dostępu w całej domenie.
- Kliknij Dodaj domenę.
- W polu Identyfikator klienta wpisz identyfikator klienta konta usługi. Identyfikator klienta konta usługi znajdziesz na stronie Konta usługi.
- W polu Zakresy OAuth (rozdzielone przecinkami) wpisz listę zakresów, do których Twoja aplikacja powinna mieć dostęp. Jeśli na przykład aplikacja potrzebuje pełnego dostępu w całej domenie do interfejsów Google Drive API i Kalendarza Google API, wpisz: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
- Kliknij Autoryzuj.
Aplikacja ma teraz uprawnienia do wywoływania interfejsu API jako użytkownicy w domenie Workspace (do „podszywania się” pod użytkowników). Gdy przygotowujesz się do wykonania tych wywołań interfejsu API z uprawnieniami delegowanymi, musisz wyraźnie określić użytkownika, którego tożsamość chcesz przyjąć.
Wywoływanie interfejsu API w imieniu użytkownika
W sekcjach poniżej pokazujemy, jak wykonać autoryzowane wywołanie interfejsu API za pomocą biblioteki klienta interfejsów API Google lub bezpośrednio korzystając z systemu OAuth 2.0 za pomocą protokołu HTTP.
Java
Po uzyskaniu adresu e-mail klienta i klucza prywatnego z konsoli interfejsów API użyj biblioteki uwierzytelniania Google w Javie, aby utworzyć obiekt GoogleCredentials na podstawie danych logowania konta usługi i zakresów, do których Twoja aplikacja potrzebuje dostępu. Na przykład:
import com.google.auth.oauth2.GoogleCredentials; import com.google.api.services.sqladmin.SQLAdminScopes; // ... GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("ServiceAccountKey.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));
Jeśli tworzysz aplikację w Google Cloud, możesz zamiast tego użyć domyślnych danych logowania aplikacji, co może uprościć ten proces.
Przekazywanie uprawnień w całej domenie
Jeśli konto usługi ma przekazany dostęp w obrębie całej domeny i chcesz przyjąć tożsamość konta użytkownika, podaj adres e-mail tego konta za pomocą metody createDelegated obiektu GoogleCredentials. Na przykład:
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("ServiceAccountKey.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN)) .createDelegated("workspace-user@example.com");
Obiekt GoogleCredentials służy do wywoływania metody createDelegated(). Argumentem metody createDelegated() musi być użytkownik należący do Twojego konta Workspace. Kod wysyłający żądanie będzie używać tych danych logowania do wywoływania interfejsów API Google przy użyciu konta usługi.
Python
Po uzyskaniu adresu e-mail klienta i klucza prywatnego z konsoli interfejsu API wykonaj te czynności, korzystając z biblioteki klienta interfejsu API Google dla języka Python:
- Utwórz obiekt
Credentialsna podstawie danych logowania konta usługi i zakresów, do których Twoja aplikacja potrzebuje dostępu. Na przykład:from google.oauth2 import service_account SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin'] SERVICE_ACCOUNT_FILE = '/path/to/ServiceAccountKey.json' credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES)
Jeśli tworzysz aplikację w Google Cloud, możesz zamiast tego użyć domyślnych danych logowania aplikacji, co może uprościć ten proces.
- Przekazywanie uprawnień w całej domenie
Jeśli masz przekazany dostęp do całej domeny na konto usługi i chcesz przyjąć tożsamość konta użytkownika, użyj metody
with_subjectistniejącego obiektuServiceAccountCredentials. Na przykład:delegated_credentials = credentials.with_subject('user@example.org')
Używaj obiektu Credentials do wywoływania interfejsów API Google w aplikacji.
HTTP/REST
Po uzyskaniu identyfikatora klienta i klucza prywatnego z konsoli interfejsu API aplikacja musi wykonać te czynności:
- Utwórz token sieciowy JSON (JWT, wymawiany „dżot”), który zawiera nagłówek, zbiór deklaracji i podpis.
- Poproś serwer autoryzacji Google OAuth 2.0 o token dostępu.
- Obsłuż odpowiedź JSON zwracaną przez serwer autoryzacji.
W kolejnych sekcjach opisujemy, jak wykonać te czynności.
Jeśli odpowiedź zawiera token dostępu, możesz go użyć do wywołania interfejsu Google API. (Jeśli odpowiedź nie zawiera tokena dostępu, token JWT i żądanie tokena mogą być nieprawidłowo sformułowane lub konto usługi może nie mieć uprawnień dostępu do żądanych zakresów).
Gdy token dostępu wygaśnie, aplikacja generuje kolejny token JWT, podpisuje go i wysyła żądanie kolejnego tokena dostępu.
W pozostałej części tej sekcji opisujemy szczegóły tworzenia i podpisywania tokena JWT, tworzenia żądania tokena dostępu oraz obsługi odpowiedzi.
Tworzenie tokena JWT
Token JWT składa się z 3 części: nagłówka, zbioru deklaracji i podpisu. Nagłówek i zbiór deklaracji to obiekty JSON. Te obiekty JSON są serializowane do bajtów UTF-8, a następnie kodowane przy użyciu kodowania Base64url. To kodowanie zapewnia odporność na zmiany kodowania wynikające z powtarzających się operacji kodowania. Nagłówek, zbiór roszczeń i podpis są łączone za pomocą znaku kropki (.).
Token JWT składa się z tych elementów:
{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}Ciąg bazowy podpisu wygląda tak:
{Base64url encoded header}.{Base64url encoded claim set}Tworzenie nagłówka JWT
Nagłówek składa się z 2 pól wymaganych: algorytmu podpisywania i formatu asercji, oraz opcjonalnego identyfikatora klucza:
- Algorytm jest obowiązkowy i ma tylko jedną wartość:
"alg": "RS256". - Format jest obowiązkowy i ma tylko jedną wartość:
"typ": "JWT". - Identyfikator klucza jest opcjonalny i jest identyfikatorem klucza konta usługi używanego do podpisywania tokena JWT. Jeśli podasz nieprawidłowy identyfikator klucza, zostaną wypróbowane wszystkie klucze powiązane z kontem usługi. Jeśli nie znajdzie prawidłowego klucza, token zostanie odrzucony. Google zastrzega sobie prawo do odrzucania tokenów z nieprawidłowymi identyfikatorami kluczy.
Konta usługi korzystają z algorytmu RSA SHA-256 i formatu tokena JWT. W rezultacie reprezentacja JSON nagłówka wygląda tak:
{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}
Reprezentacja Base64url tego ciągu wygląda tak:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Tworzenie zestawu deklaracji JWT
Zbiór deklaracji JWT zawiera informacje o JWT, w tym o żądanych uprawnieniach (zakresach), celu tokena, wystawcy, czasie wydania tokena i jego okresie ważności. Większość pól jest obowiązkowa. Podobnie jak nagłówek JWT, zbiór deklaracji JWT jest obiektem JSON i jest używany do obliczania podpisu.
Wymagane roszczenia
Wymagane deklaracje w zbiorze deklaracji JWT mogą występować w dowolnej kolejności.
| Nazwa | Opis |
|---|---|
iss |
Adres e-mail konta usługi. |
scope |
Lista uprawnień, których żąda aplikacja, oddzielonych spacjami. |
aud |
Opis docelowego odbiorcy potwierdzenia. Podczas wysyłania prośby o token dostępu ta wartość jest zawsze równa https://oauth2.googleapis.com/token. |
exp |
Czas wygaśnięcia asercji podany w sekundach od godziny 00:00:00 czasu UTC 1 stycznia 1970 r. Wartość ta może wynosić maksymalnie 1 godzinę od czasu wydania. |
iat |
Czas wydania asercji podany w sekundach od 00:00:00 UTC, 1 stycznia 1970 r. |
Oto przykład reprezentacji JSON wymaganych pól w zbiorze deklaracji JWT:
{ "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 }
Dodatkowe roszczenia
W przypadku niektórych firm aplikacja może używać przekazywania dostępu w całej domenie, aby działać w imieniu konkretnego użytkownika w organizacji. Zanim aplikacja będzie mogła podszywać się pod użytkownika, musi otrzymać uprawnienie do tego typu podszywania się. Zwykle zajmuje się tym superadministrator. Więcej informacji znajdziesz w artykule Kontrola dostępu do interfejsów API przy użyciu przekazywania dostępu w całej domenie.
Aby uzyskać token dostępu, który przyznaje aplikacji przekazywanie dostępu do zasobu, w zbiorze deklaracji JWT umieść adres e-mail użytkownika jako wartość pola sub.
| Nazwa | Opis |
|---|---|
sub |
Adres e-mail użytkownika, w przypadku którego aplikacja prosi o dostęp delegowany. |
Jeśli aplikacja nie ma uprawnień do przyjmowania tożsamości użytkownika, odpowiedź na żądanie tokena dostępu zawierające pole sub będzie błędem.
Oto przykład zestawu roszczeń JWT zawierającego pole 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 }
Kodowanie zbioru deklaracji JWT
Podobnie jak nagłówek JWT, zestaw deklaracji JWT powinien być serializowany do formatu UTF-8 i zakodowany w formacie Base64url-safe. Oto przykład reprezentacji JSON zestawu roszczeń JWT:
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope": "https://www.googleapis.com/auth/prediction", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
Obliczanie podpisu
JSON Web Signature (JWS) to specyfikacja, która określa mechanizm generowania podpisu dla tokena JWT. Dane wejściowe podpisu to tablica bajtów zawierająca te treści:
{Base64url encoded header}.{Base64url encoded claim set}Podczas obliczania podpisu należy użyć algorytmu podpisywania w nagłówku JWT. Jedynym algorytmem podpisywania obsługiwanym przez serwer autoryzacji Google OAuth 2.0 jest RSA z algorytmem haszowania SHA-256. Jest to wyrażone jako RS256 w polu alg
w nagłówku tokena JWT.
Podpisz reprezentację wejściową w formacie UTF-8 za pomocą SHA256withRSA (znanego też jako RSASSA-PKCS1-V1_5-SIGN z funkcją skrótu SHA-256) przy użyciu klucza prywatnego uzyskanego z Konsoli interfejsów API Google. Dane wyjściowe będą tablicą bajtów.
Podpis musi być następnie zakodowany w formacie Base64url. Nagłówek, zbiór roszczeń i podpis są łączone za pomocą znaku kropki (.). Wynikiem jest JWT. Powinien on wyglądać tak (podziały wierszy dodane w celu uniknięcia wątpliwości):
{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}Oto przykład tokena JWT przed zakodowaniem w formacie Base64url:
{"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]Oto przykład podpisanego tokena JWT gotowego do przesłania:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ
Prośba o token dostępu
Po wygenerowaniu podpisanego tokena JWT aplikacja może go użyć do wysłania żądania tokena dostępu.
To żądanie tokena dostępu jest żądaniem HTTPS POST, a jego treść jest zakodowana w formacie URL. Na przykład:
https://oauth2.googleapis.com/token
Żądanie HTTPS POST musi zawierać te parametry:
| Nazwa | Opis |
|---|---|
grant_type |
Użyj tego ciągu znaków, w razie potrzeby zakodowanego w formacie URL:urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion |
Token JWT, w tym podpis. |
To jest surowy zrzut żądania HTTPS POST użytego w żądaniu tokena dostępu:
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
To to samo żądanie, ale z użyciem parametru 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
Obsługa odpowiedzi
Jeśli token JWT i żądanie tokena dostępu są prawidłowo sformułowane, a konto usługi ma uprawnienia do wykonania operacji, odpowiedź serwera autoryzacji w formacie JSON zawiera token dostępu. Oto przykładowa odpowiedź:
{ "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "scope": "https://www.googleapis.com/auth/prediction" "token_type": "Bearer", "expires_in": 3600 }
Tokeny dostępu można ponownie wykorzystywać w okresie określonym przez wartość expires_in.
Ważna kwestia dotycząca bezpieczeństwa: zrozumienie podszywania się
Gdy przekazujesz uprawnienia w całej domenie, nie przyznajesz kontu usługi bezpośredniego dostępu do wszystkich danych użytkowników. Zamiast tego autoryzujesz ją do podszywania się pod konkretnych użytkowników podczas wykonywania wywołań interfejsu API.- Dostęp w imieniu użytkownika: w przypadku każdego żądania wysyłanego do interfejsu API aplikacja musi określać, którego użytkownika ma reprezentować. Aplikacja działa wtedy z uprawnieniami tego konkretnego użytkownika, a nie z żadnymi podwyższonymi ani uprawnieniami w całej domenie.
- Ograniczone uprawnienia: dostęp konta usługi jest ograniczony przez 2 czynniki: uprawnienia użytkownika, którego tożsamość jest podszywana, oraz zakresy OAuth autoryzowane w konsoli administracyjnej. Nie ma dostępu do danych, do których nie ma dostępu użytkownik, którego tożsamość jest podszywana.
- Zasada jak najmniejszych uprawnień: ta funkcja umożliwia dostęp do danych użytkownika bez jego bezpośredniej zgody, dlatego ważne jest, aby przestrzegać najlepszych praktyk w zakresie bezpieczeństwa. Przyznawaj tylko niezbędne zakresy OAuth i upewnij się, że rozumiesz konsekwencje dla bezpieczeństwa.
Wywoływanie interfejsów API Google
Java
Aby wywołać interfejsy API Google, użyj obiektu GoogleCredentials, wykonując te czynności:
- Utwórz obiekt usługi dla interfejsu API, który chcesz wywołać, używając obiektu
GoogleCredentials. Na przykład:SQLAdmin sqladmin = new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credentials).build();
- Wysyłaj żądania do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi.
Aby na przykład wyświetlić listę instancji baz danych Cloud SQL w projekcie exciting-example-123:
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
Python
Aby wywołać interfejsy API Google, użyj autoryzowanego obiektu Credentials, wykonując te czynności:
- Utwórz obiekt usługi dla interfejsu API, który chcesz wywołać. Obiekt usługi tworzy się, wywołując funkcję
buildz nazwą i wersją interfejsu API oraz autoryzowanym obiektemCredentials. Na przykład, aby wywołać wersję 1beta3 interfejsu Cloud SQL Administration API:import googleapiclient.discovery sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
- Wysyłaj żądania do usługi API za pomocą interfejsu udostępnianego przez obiekt usługi.
Aby na przykład wyświetlić listę instancji baz danych Cloud SQL w projekcie exciting-example-123:
response = sqladmin.instances().list(project='exciting-example-123').execute()
HTTP/REST
Gdy aplikacja uzyska token dostępu, może go używać do wywoływania interfejsu API Google w imieniu danego konta usługi lub konta użytkownika, jeśli przyznano zakresy dostępu wymagane przez interfejs API. Aby to zrobić, uwzględnij token dostępu w żądaniu do interfejsu API, dodając parametr zapytania access_token lub wartość nagłówka HTTP AuthorizationBearer. W miarę możliwości preferowany jest nagłówek HTTP, ponieważ ciągi zapytań są zwykle widoczne w logach serwera. W większości przypadków możesz użyć biblioteki klienta, aby skonfigurować wywołania interfejsów API Google (np. podczas wywoływania interfejsu Drive Files API).
Wszystkie interfejsy API Google i ich zakresy możesz wypróbować na stronie OAuth 2.0 Playground.
Przykłady żądań HTTP GET
Wywołanie punktu końcowego
drive.files (interfejs Drive Files API) za pomocą nagłówka HTTP Authorization: Bearer może wyglądać tak: Pamiętaj, że musisz podać własny token dostępu:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Oto wywołanie tego samego interfejsu API dla uwierzytelnionego użytkownika za pomocą parametru ciągu zapytania access_token:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl przykładu
Możesz przetestować te polecenia za pomocą aplikacji wiersza poleceń curl. Oto przykład, w którym użyto opcji nagłówka HTTP (preferowanej):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
Możesz też wybrać opcję parametru ciągu zapytania:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Wygaśnięcie tokenów dostępu
Tokeny dostępu wydawane przez serwer autoryzacji Google OAuth 2.0 wygasają po upływie czasu określonego przez wartość expires_in. Gdy token dostępu wygaśnie, aplikacja powinna wygenerować kolejny token JWT, podpisać go i poprosić o kolejny token dostępu.
Kody błędów JWT
error pole |
error_description pole |
Znaczenie | Jak rozwiązać problem |
|---|---|---|---|
unauthorized_client |
Unauthorized client or scope in request. |
Jeśli próbujesz użyć przekazywania dostępu w całej domenie, konto usługi nie jest autoryzowane w konsoli administracyjnej domeny użytkownika. |
Sprawdź, czy konto usługi jest autoryzowane na stronie Przekazywanie dostępu w całej domenie w konsoli administracyjnej dla użytkownika w roszczeniu (polu) Zwykle zajmuje to kilka minut, ale zastosowanie autoryzacji na wszystkich kontach użytkowników na Twoim koncie Google może potrwać do 24 godzin. |
unauthorized_client |
Client is unauthorized to retrieve access tokens using this method, or client not
authorized for any of the scopes requested. |
Konto usługi zostało autoryzowane w konsoli administracyjnej przy użyciu adresu e-mail klienta zamiast identyfikatora klienta (liczbowego) lub do autoryzacji użyto grupy dyskusyjnej Google. | Na stronie Przekazywanie dostępu w całej domenie w konsoli administracyjnej usuń klienta i dodaj go ponownie, używając identyfikatora numerycznego. Możesz też usunąć grupę dyskusyjną Google i zastąpić ją pojedynczą usługą lub kontem użytkownika. |
access_denied |
(dowolna wartość) | Jeśli używasz przekazywania dostępu w całej domenie, co najmniej 1 z zakresów nie jest autoryzowany w konsoli administracyjnej. |
Sprawdź, czy konto usługi jest autoryzowane na stronie
Przekazywanie dostępu w całej domenie w konsoli administracyjnej dla użytkownika w deklaracji Sprawdź, czy dostęp do usług Google nie jest ograniczony. W tym celu zapoznaj się z artykułem Zarządzanie dostępem do usług, które nie mają własnych opcji włączania i wyłączania. Zwykle zajmuje to kilka minut, ale zastosowanie autoryzacji na wszystkich kontach użytkowników na Twoim koncie Google może potrwać do 24 godzin. |
admin_policy_enforced |
(dowolna wartość) | Konto Google nie może autoryzować co najmniej jednego z żądanych zakresów z powodu zasad administratora Google Workspace. |
Więcej informacji o tym, jak administrator może ograniczyć dostęp do wszystkich zakresów lub zakresów wrażliwych i ograniczonych, dopóki nie zostanie on wyraźnie przyznany identyfikatorowi klienta OAuth, znajdziesz w artykule pomocy dla administratorów Google Workspace Określanie, które aplikacje innych firm i aplikacje wewnętrzne mają dostęp do danych Google Workspace. |
invalid_client |
(dowolna wartość) |
Klient OAuth lub token JWT jest nieprawidłowy lub niepoprawnie skonfigurowany. Szczegółowe informacje znajdziesz w opisie błędu. |
Sprawdź, czy token JWT jest prawidłowy i zawiera poprawne deklaracje. Sprawdź, czy klient OAuth i konto usługi są poprawnie skonfigurowane i czy używasz właściwego adresu e-mail. Sprawdź, czy token JWT jest prawidłowy i czy został wydany dla identyfikatora klienta w żądaniu. |
deleted_client |
(dowolna wartość) |
Klient OAuth używany do wysyłania żądania został usunięty. Usuwanie może odbywać się ręcznie lub automatycznie w przypadku nieużywanych klientów . Usuniętych klientów można przywrócić w ciągu 30 dni od usunięcia. Więcej informacji |
Użyj identyfikatora klienta, który jest nadal aktywny. |
invalid_grant |
Not a valid email lub Invalid email or User ID. |
Użytkownik nie istnieje. | Sprawdź, czy adres e-mail w sub (polu) jest prawidłowy. |
invalid_grant |
|
Zwykle oznacza to, że czas systemowy na urządzeniu lokalnym jest nieprawidłowy. Może się to też zdarzyć, jeśli wartość exp jest o ponad 65 minut późniejsza niż wartość iat lub jeśli wartość exp jest mniejsza niż wartość iat. |
Sprawdź, czy zegar w systemie, w którym generowany jest JWT, jest prawidłowy. W razie potrzeby zsynchronizuj czas z protokołem NTP Google. |
invalid_grant |
Invalid JWT Signature. |
Asercja JWT jest podpisana kluczem prywatnym, który nie jest powiązany z kontem usługi identyfikowanym przez adres e-mail klienta, lub klucz, który został użyty, został usunięty, wyłączony lub utracił ważność. Alternatywnie asercja JWT może być nieprawidłowo zakodowana – musi być zakodowana w standardzie Base64, bez znaków nowego wiersza ani znaków równości dopełniających. |
Zdekoduj zestaw deklaracji JWT i sprawdź, czy klucz, którym podpisano asercję, jest powiązany z kontem usługi. Spróbuj użyć biblioteki OAuth udostępnionej przez Google, aby mieć pewność, że token JWT jest generowany prawidłowo. |
invalid_scope |
Invalid OAuth scope or ID token audience provided. |
Nie zażądano żadnych zakresów (pusta lista zakresów) lub jeden z zażądanych zakresów nie istnieje (jest nieprawidłowy). |
Sprawdź, czy roszczenie Pamiętaj, że lista zakresów w deklaracji |
disabled_client |
The OAuth client was disabled. |
Klucz użyty do podpisania asercji JWT jest wyłączony. |
Otwórz Konsolę interfejsów API Google i w sekcji Uprawnienia > Konta usługi włącz konto usługi, które zawiera „Identyfikator klucza” używany do podpisywania asercji. |
org_internal |
This client is restricted to users within its organization. |
Identyfikator klienta OAuth w żądaniu jest częścią projektu, który ogranicza dostęp do kont Google w określonej organizacji Google Cloud. |
Uwierzytelnij się za pomocą konta usługi w organizacji. Potwierdź konfigurację typu użytkownika w przypadku aplikacji OAuth. |
Dodatek: autoryzacja za pomocą konta usługi bez OAuth
W przypadku niektórych interfejsów API Google możesz wykonywać autoryzowane wywołania interfejsu API, używając podpisanego tokena JWT bezpośrednio jako tokena okaziciela, a nie tokena dostępu OAuth 2.0. Jeśli jest to możliwe, możesz uniknąć wysyłania żądania sieciowego do serwera autoryzacji Google przed wykonaniem wywołania interfejsu API.
Jeśli interfejs API, którego chcesz użyć, ma definicję usługi opublikowaną w repozytorium interfejsów API Google w GitHub, możesz wykonywać autoryzowane wywołania interfejsu API za pomocą tokena JWT zamiast tokena dostępu. Aby to zrobić:
- Utwórz konto usługi Pamiętaj, aby zachować plik JSON, który otrzymasz podczas tworzenia konta.
- Korzystając z dowolnej standardowej biblioteki JWT, np. tej dostępnej na stronie jwt.io, utwórz token JWT z nagłówkiem i ładunkiem podobnym do tego w przykładzie poniżej:
{ "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 }
- W polu
kidw nagłówku podaj identyfikator klucza prywatnego konta usługi. Znajdziesz go w poluprivate_key_idpliku JSON konta usługi. - W polach
issisubpodaj adres e-mail konta usługi. Tę wartość znajdziesz w poluclient_emailpliku JSON konta usługi. Ta wartość jednoznacznie identyfikuje klienta i jest funkcjonalnie identyfikatorem klienta. - W polu
audpodaj punkt końcowy API. Na przykład:https://SERVICE.googleapis.com/. - W polu
iatpodaj bieżący czas epoki systemu Unix, a w poluexppodaj czas dokładnie 3600 sekund później, kiedy token JWT wygaśnie.
Podpisz token JWT za pomocą algorytmu RSA-256, używając klucza prywatnego znajdującego się w pliku JSON konta usługi.
Na przykład:
Java
Używanie google-auth-library-java i java-jwt:
import com.google.auth.oauth2.ServiceAccountCredentials; ... GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")); PrivateKey privateKey = ((ServiceAccountCredentials) credentials).getPrivateKey(); String privateKeyId = ((ServiceAccountCredentials) credentials).getPrivateKeyId(); 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
Używanie 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')
- Wywołaj interfejs API, używając podpisanego tokena JWT jako tokena okaziciela:
GET /v1/projects/abc/databases/123/indexes HTTP/1.1 Authorization: Bearer SIGNED_JWT Host: firestore.googleapis.com
Wdrażanie Ochrony wszystkich kont
Dodatkowym krokiem, który należy podjąć w celu ochrony kont użytkowników, jest wdrożenie ochrony wszystkich kont za pomocą usługi ochrony wszystkich kont Google. Ta usługa umożliwia subskrybowanie powiadomień o zdarzeniach związanych z bezpieczeństwem, które dostarczają aplikacji informacji o ważnych zmianach na koncie użytkownika. Na podstawie tych informacji możesz podejmować działania w zależności od tego, jak chcesz reagować na zdarzenia.
Oto kilka przykładów typów zdarzeń wysyłanych do Twojej aplikacji przez usługę Ochrona wszystkich kont Google:
-
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
Więcej informacji o wdrażaniu ochrony wszystkich kont i pełną listę dostępnych zdarzeń znajdziesz na stronie dotyczącej ochrony kont użytkowników za pomocą ochrony wszystkich kont .