#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.
У вас есть два варианта:
- Используйте свой метод и сохраните существующий файл ключа JSON учетной записи службы в Secret Manager. Это безопасный и рекомендуемый метод. Этот метод требует добавления роли IAM для доступа к секретам, хранящимся в Secret Manager. Вы правы в том, что у вас есть дополнительная задача по управлению файлом ключа JSON учетной записи службы как для обеспечения безопасности, так и для развертывания.
- Используйте подпись IAM. Поскольку сервер метаданных не предоставляет доступ к закрытому ключу, Google предоставляет API для подписи данных. Этот метод также безопасен и рекомендуется. Этот метод требует добавления разрешения IAM iam.ServiceAccounts.signBlob, которое включено в роли, такие как создатель токена учетной записи службы (roles/iam.serviceAccountTokenCreator).
Следующий API устарел. Я включаю его, потому что есть хороший пример C #, показывающий, как использовать API. Аналогичный метод работает с новым API. Основное различие между этим API и новым API заключается в добавлении делегатов, которые вам не требуются. Делегаты — это идентификаторы, связанные с олицетворением (делегированием).
Метод: projects.ServiceAccounts.signBlob
Новый API:
Комментарии:
1. Спасибо за ваш подробный ответ!