Получить текущую учетную запись службы в GCR

#c# #google-cloud-run #service-accounts #google-iam #google-cloud-iam

#c# #google-cloud-запустить #сервисные учетные записи #google-iam #google-cloud-iam

Вопрос:

Проблема

Я запускаю приложение ASP Core в GCR, и мне нужно получить текущее ServiceAccountCredential значение, чтобы подписывать URL-адреса. Очевидный способ сделать это:

 var credential = GoogleCredential.GetApplicationDefault();
var serviceCred = (ServiceAccountCredential)credential.UnderlyingCredential;
var urlSigner = UrlSigner.FromServiceAccountCredential(serviceCred);
 

Вопреки моим ожиданиям, UnderlyingCredential возвращаемое GoogleCredential.GetApplicationDefault является экземпляром ComputeCredential (хотя служба GCR запущена в учетной записи службы, которую я создал специально для этой цели).

Следствием этого InvalidCastException является то, что возникает сообщение об ошибке: Unable to cast object of type 'Google.Apis.Auth.OAuth2.ComputeCredential' to type 'Google.Apis.Auth.OAuth2.ServiceAccountCredential' .

Обходной путь

В качестве обходного пути я создал ключ для учетной записи службы, сохранил его в секретном менеджере и использую его вместо этого:

 var credential = GoogleCredential.FromJson(credJson);
var serviceCred = (ServiceAccountCredential)credential.UnderlyingCredential;
var urlSigner = UrlSigner.FromServiceAccountCredential(serviceCred);
 

Решение?

Хотя обходной путь работает, я бы предпочел вообще не создавать ключ, просто чтобы избежать разброса ключей. Есть ли правильное решение, которое я мог бы использовать для извлечения текущей ServiceAccountCredential ? Или, в противном случае, для подписи URL-адресов с помощью ComputeCredential ?

Ответ №1:

Учетные данные приложения по умолчанию — это метод получения учетных данных. В вашем случае службе GCR назначена учетная запись службы. Вычислительные функции предоставляются Compute Engine, и именно поэтому вы видите ComputeEngine в качестве типа учетных данных. Эти учетные данные создаются службой метаданных, подключенной к экземпляру Compute Engine.

Служба метаданных предоставляет токены — токены доступа и удостоверения OAuth 2.0. Сервер метаданных не предоставляет закрытый ключ учетной записи службы, который требуется для подписи данных (URL-адресов). Поэтому вы не можете использовать учетные данные, созданные сервером метаданных, для подписи данных, которые Google называет blob.

У вас есть два варианта:

  1. Используйте свой метод и сохраните существующий файл ключа JSON учетной записи службы в Secret Manager. Это безопасный и рекомендуемый метод. Этот метод требует добавления роли IAM для доступа к секретам, хранящимся в Secret Manager. Вы правы в том, что у вас есть дополнительная задача по управлению файлом ключа JSON учетной записи службы как для обеспечения безопасности, так и для развертывания.
  2. Используйте подпись IAM. Поскольку сервер метаданных не предоставляет доступ к закрытому ключу, Google предоставляет API для подписи данных. Этот метод также безопасен и рекомендуется. Этот метод требует добавления разрешения IAM iam.ServiceAccounts.signBlob, которое включено в роли, такие как создатель токена учетной записи службы (roles/iam.serviceAccountTokenCreator).

Следующий API устарел. Я включаю его, потому что есть хороший пример C #, показывающий, как использовать API. Аналогичный метод работает с новым API. Основное различие между этим API и новым API заключается в добавлении делегатов, которые вам не требуются. Делегаты — это идентификаторы, связанные с олицетворением (делегированием).

Метод: projects.ServiceAccounts.signBlob

Новый API:

Метод: projects.ServiceAccounts.signBlob

Комментарии:

1. Спасибо за ваш подробный ответ!