Создайте токен долгосрочного доступа для сервисного аккаунта для доступа к API Google

У меня есть аккаунт сервиса foo. Для этой учетной записи службы я хочу создать токен авторизации, чтобы я мог запустить свою программу в конвейере CI/CD и позволить ей взаимодействовать с API Google.

Я исследовал, как получить долгосрочный токен, просмотрев эту документацию: https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth

Моя проблема в том, что мне нужно сделать так много шагов только ради этого токена.

  • Создайте заголовок JWT и заявите
  • Создать подпись для JWT
  • Используйте созданный JWT для фактического получения токена аутентификации.
  • Использовать токен аутентификации...

Почему я не могу использовать токен JWT для доступа к API Google? Почему мне нужно запрашивать еще один токен? Честно говоря, это кажется немного переработанным.

Что для вас означает «долгосрочная перспектива»?

guillaume blaquiere 15.04.2024 12:54
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
1
1
576
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как упоминалось в этом блоге:

OAuth: открытая авторизация (OAuth) — это открытый стандарт аутентификации на основе токенов в общедоступных сетях. OAuth позволяет сторонние сервисы, такие как Facebook и Google, для использования конечным пользователем. информацию об учетной записи, не раскрывая учетные данные пользователя третий участник.

JWT: Веб-токены JSON (JWT) представляют собой открытый отраслевой стандарт для обмена информацией между двумя объектами, обычно клиентом ( интерфейс приложения) и сервер (внутренняя часть приложения). приложение).

JWT — это токен, содержащий утверждения о пользователе или клиенте. OAuth использует уникальный токен для предоставления доступа к ресурсам пользователя. OAuth токены — это токены безопасности, предоставленные IDP, которые можно только проверить. тем же поставщиком токенов OAuth. Вы можете использовать JWT как еще один вид Токен OAuth.

JWT лучше подходит для API. OAuth полезен для Интернета, API и браузерные приложения и ресурсы.

Срок действия токена доступа может быть продлен. Для этого выберите учетные записи служб, которым требуется расширенный срок действия токенов доступа, а затем добавьте эти учетные записи служб в политику организации, которая включает ограничение списка ограничений/iam.allowServiceAccountCredentialLifetimeExtension.

Если вы хотите продлить срок действия токена сверх значения по умолчанию, вам необходимо создать политику организации, которая включает ограничение iam.allowServiceAccountCredentialLifetimeExtension. Вы не можете создавать токены доступа с увеличенным сроком действия для учетных данных пользователя или внешних удостоверений. Дополнительную информацию можно найти в этом официальном документе GCP .

Согласно официальному документу GCP Создайте токен доступа:

Если вы используете REST API и ваша система настроена на разрешение расширенный срок действия токена, вы можете создать токен со сроком действия длиннее, чем по умолчанию. Google Cloud CLI не поддерживает настройку жизнь для токена.

Теперь о том, «Почему я вообще не могу использовать токен JWT для доступа к API Google?» »

Токен JWT действителен только в течение короткого периода времени (обычно один час) и не может использоваться для прямого доступа к API Google. Использование токена JWT может показаться дополнительным шагом и немного переусложненным. Он добавляет дополнительный уровень безопасности и гарантирует, что только авторизованные пользователи получат доступ к API Google, он обеспечивает более безопасный способ доступа к API Google и предотвращает неправильное использование ресурсов API.

Почему мне нужно запрашивать еще один токен?

Еще один или двухэтапный процесс помогает повысить безопасность, гарантируя, что ваш токен JWT не будет скомпрометирован. Если ваш токен JWT украден, его можно использовать только для запроса токена доступа, срок действия которого истечет через короткий период времени. Это помогает защитить ваши ресурсы Google API от несанкционированного доступа.

Дополнительную информацию можно найти в обсуждениях на форуме сообщества Google Cloud .

На самом деле это может зависеть от API Google, который вам нужно вызвать. Я считаю, что моя ситуация похожа на вашу, и я исследовал ее несколько дней. Я не могу поверить, насколько сложным это сделал Google, но, к счастью, для моих нужд вызова API Google Cloud Secret Manager через HTTP REST я могу использовать то, что они называют «самозаверяющим JWT». Техническую документацию по этому вопросу можно найти по адресу: https://google.aip.dev/auth/4111. Но похоже, что у вас есть эта часть.

Следующая часть информации, которую я нашел, была по той же ссылке, которую вы указали: https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth

Говорится:

С помощью некоторых API Google вы можете выполнять авторизованные вызовы API, используя подписанный JWT непосредственно в качестве токена-носителя, а не токен доступа OAuth 2.0. Если это возможно, вы можете избежать необходимости отправлять сетевой запрос на сервер авторизации Google перед вызовом API.

Это именно то, чего я хочу. И звучит так же, как и вы. Поэтому вам может быть полезно упомянуть, какие именно API Google вам нужно вызывать. В документации далее говорится:

Если API, который вы хотите вызвать, имеет определение службы, опубликованное в репозитории Google API GitHub, вы можете выполнять авторизованные вызовы API, используя JWT вместо токена доступа.

Я не совсем понимаю, что они подразумевают под «...опубликовано определение сервиса...». Но, например, здесь есть «папка» для Google Cloud Secret Manager . Если это то, что они подразумевают под «...опубликовано определение сервиса...», то, будем надеяться, это хороший знак, потому что их много. Надеюсь, там есть то, что вам нужно.

Учитывая это, я могу затем просто просмотреть документацию по этому API и сделать простой запрос HTTP REST, содержащий мой самозаверяющий JWT. Например, чтобы получить последнюю версию секрета, я могу сгенерировать новый самозаверяющий JWT со сроком действия один час, а затем выполнить HTTP-вызов:

GET https://secretmanager.googleapis.com/v1/projects/my-company-project-name/secrets/my-secret-name/versions/latest:access
Authorization: Bearer ey0asdfasdf....

И мне никогда не придется проходить какие-либо «многоэтапные» шаги OAuth, беспокоиться об истечении срока действия токенов или обновлении токенов. Эта часть потрясающая. Но почему Google считает, что это лучше или безопаснее, чем использование ключа API, мне непонятно. По крайней мере, с помощью ключа API Google позволяет вам не только устанавливать очевидные ограничения разрешений относительно того, к чему можно использовать ключ API, но также делать такие вещи, как наложение на него ограничений по IP-адресу. Вы не можете сделать это с самоподписанными JWT. К сожалению, очень немногие API Google позволяют использовать ключи API.

Вот снимок экрана со списком закрытых ключей моей учетной записи службы. Созданный закрытый ключ (небольшой файл JSON) будет загружен через ваш браузер и срок его действия никогда не истечет.

Когда у вас есть все это, для меня появилась последняя ключевая (без каламбура) информация: https://stackoverflow.com/a/66489363/8169136 в котором упоминается, что для многих клиентских библиотек SDK Google API нужно сделать что-то простое, например указать местоположение файла закрытого ключа JSON, а не использовать их дурацкие «Учетные данные приложения по умолчанию» (привет, я в замешательстве). многопользовательскую серверную среду), вы можете сделать это, используя класс *Builder клиентской библиотеки API. Итак, опять же, с помощью API Secret Manager я мог бы сделать:

// https://stackoverflow.com/a/66489363/8169136
var text = File.ReadAllText(@"C:\GoogleCloudSecretManager\application_default_credentials.json");
var secretManagerServiceClientBuilder = new SecretManagerServiceClientBuilder
{
    JsonCredentials = text,
};

var client = secretManagerServiceClientBuilder.Build();
var secretVersionName = new SecretVersionName(projectID, secretID, secretVersionID);

// Call the API.
var result = client.AccessSecretVersion(secretVersionName);

// Convert the payload to a string. Payloads are bytes by default.
var payload = result.Payload.Data.ToStringUtf8();

Log(payload);

Я не могу поверить, что потребовалось несколько дней исследований, чтобы получить четкое представление и написать эти несколько строк кода.

На всякий случай, для справки, закрытый ключ сервисной учетной записи, который загружается в виде файла JSON, должен выглядеть примерно так:

Обратите внимание: я просто назвал файл application_default_credentials.json, чтобы сначала заставить его работать с примером кода по умолчанию, основанным на существовании файла с таким именем в каталоге %APPDATA%\gcloud\ (в Windows).

P.S. Есть еще одна часть, которую я хотел бы сделать, но которую я еще не придумал, но похоже, что вы, возможно, уже это поняли. Вы упомянули, что это похоже на создание самозаверяющего JWT, а затем использование его для вызова Google для получения токена OAuth. Какой это будет HTTP-вызов? Я хотел бы, чтобы мое приложение делало это как однократную операцию «тестового соединения». Я пробовал многое, но не могу использовать свой самозаверяющий JWT ни для чего, кроме единственного секрета, на который я предоставил разрешения своей сервисной учетной записи. Возможно, мне нужно предоставить моей сервисной учетной записи какое-то другое разрешение? Например, я пытался отправить JWT на такие вещи, как:

https://www.googleapis.com/oauth2/v1/tokeninfo

https://www.googleapis.com/oauth2/v3/userinfo?access_token=eyJhbGci...

POST https://oauth2.googleapis.com/token

Но все они возвращают какую-то ошибку, довольно неоднозначную ошибку.

Другие вопросы по теме

Проблема с использованием учетных записей служб при развертывании gke
Получение FolderID и имени папки внутри определенной папки на Google Диске
Папка на диске не создается
Загрузка на Google Диск через Python API без присмотра
Безопасно создавайте приглашения в Календарь Google, используя учетную запись службы
Как заставить Terraform использовать явную учетную запись службы GCP вместо учетной записи GCE, на которой она работает
Python, не удается отправить почту с почтового адреса рабочей области Google на отдельный адрес Gmail
Облако Google gcloud, включающее сервисы API для электронной почты сервисного аккаунта
GCP - Пользователь ... не имеет разрешения на доступ к экземпляру проекта
Получение учетных записей службы не может приглашать посетителей без делегирования полномочий на уровне домена, даже если делегирование на уровне домена уже предоставлено