在 GCR 上获取当前服务帐户
Get current service account on GCR
问题
我是 运行 GCR 上的 ASP 核心应用程序,需要检索当前的 ServiceAccountCredential
才能签署网址。显而易见的方法是:
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
?
对 url 进行签名
应用程序默认凭据是一种获取凭据的方法。在您的例子中,GCR 服务有一个分配给它的服务帐户。计算功能由 Compute Engine 提供,这就是您将 ComputeEngine 视为凭据类型的原因。这些凭据由附加到 Compute Engine 实例的元数据服务创建。
元数据服务提供令牌 - OAuth 2.0 访问和身份令牌。元数据服务器不提供签署数据 (URL) 所需的服务帐户 私钥。因此,您不能使用元数据服务器创建的凭据对 Google 调用 blobs.
的数据进行签名
您有两个选择:
使用您的方法并将现有服务帐户 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 之间的主要区别在于添加了您不需要的 delegates。委托是涉及模拟(委托)的身份。
Method: projects.serviceAccounts.signBlob
新的API:
问题
我是 运行 GCR 上的 ASP 核心应用程序,需要检索当前的 ServiceAccountCredential
才能签署网址。显而易见的方法是:
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
?
应用程序默认凭据是一种获取凭据的方法。在您的例子中,GCR 服务有一个分配给它的服务帐户。计算功能由 Compute Engine 提供,这就是您将 ComputeEngine 视为凭据类型的原因。这些凭据由附加到 Compute Engine 实例的元数据服务创建。
元数据服务提供令牌 - OAuth 2.0 访问和身份令牌。元数据服务器不提供签署数据 (URL) 所需的服务帐户 私钥。因此,您不能使用元数据服务器创建的凭据对 Google 调用 blobs.
的数据进行签名您有两个选择:
使用您的方法并将现有服务帐户 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 之间的主要区别在于添加了您不需要的 delegates。委托是涉及模拟(委托)的身份。
Method: projects.serviceAccounts.signBlob
新的API: