在 GCR 上获取当前服务帐户

Posted

技术标签:

【中文标题】在 GCR 上获取当前服务帐户【英文标题】:Get current service account on GCR 【发布时间】:2021-12-04 17:58:48 【问题描述】:

问题

我在 GCR 上运行一个 ASP Core 应用程序,需要检索当前的 ServiceAccountCredential 才能签署 url。显而易见的方法是:

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

与我的预期相反,GoogleCredential.GetApplicationDefault 返回的 UnderlyingCredential 是一个实例 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?或者,否则,使用ComputeCredential 对网址进行签名?

【问题讨论】:

【参考方案1】:

Application Default Credentials 是一种获取凭据的方法。在您的情况下,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,该权限包含在 Service Account Token Creator (roles/iam.serviceAccountTokenCreator) 等角色中。

以下 API 已弃用。我包含它是因为有一个很好的 C# 示例展示了如何使用 API。类似的方法适用于新的 API。此 API 与新 API 的主要区别在于添加了您不需要的 委托。代表是涉及模拟(委托)的身份。

Method: projects.serviceAccounts.signBlob

新的 API:

Method: projects.serviceAccounts.signBlob

【讨论】:

感谢您的详细解答!

以上是关于在 GCR 上获取当前服务帐户的主要内容,如果未能解决你的问题,请参考以下文章

无法获取 gcr.io 上的镜像的解决方法

在不提示的情况下在 Powershell 中获取当前用户的凭据对象

无法获取 gcr.io/automl-vision-ondevice/gcloud-container-1.14.0:latest 的 docker 镜像

如何从 ASP.NET 页面获取当前登录的 Windows 帐户?

如何在 zapier 网站上获取当前的 Zapier App 版本

在没有 gcloud 的情况下获取服务帐户身份验证令牌?