Google 云:在模拟服务帐户时签署 JWT

Google Cloud: sign a JWT while impersonating a service account

目标:
我有一个云功能,可以根据提供给它的服务帐户电子邮件来模拟服务帐户。然后我想使用模拟的服务帐户来签署一个 jwt。

我试过的:
我已经像这样设置了服务帐户的模拟:

credentials = google.auth.impersonated_credentials.Credentials(
        source_credentials=SOURCE_CREDENTIALS,
        target_principal=SA_EMAIL,
        target_scopes=TARGET_SCOPES,
        lifetime=300)

这让我想到了一个子问题:我需要指定哪些目标范围?

创建模拟凭据后,我尝试使用 signer (docs) 对 JWT 的有效负载进行签名:

payload = {
        'iat': now,
        "exp": now + expiry_length,
        [...]
    }

signer = target_credentials.signer
jwt = google.auth.jwt.encode(signer, payload)

我收到的错误信息是:

AttributeError: 'Credentials' object has no attribute 'key_id'

问题:
我怀疑我使用 signer 的方法不在正确的轨道上。
如何实现我的目标?

在您的示例代码中,您只创建了有效负载部分。签名的 JWT 还需要 header.

header 看起来像这样:

header = {
        'kid': pkey_id,    # Signing Private Key ID
        "alg": "RS256",    # Google uses SHA256withRSA
        "typ": "JWT"
}

header 和 payload 是 base64 编码的,然后在中间用点(句点符号)连接。您签署组合数据。

您将遇到的问题是您需要私钥 ID(在我的示例中为 pkey_id)。该值位于服务帐户 JSON 密钥文件中。但是,Google 不会发布用于签名的 JSON 密钥文件。使用的密钥是 Google 私有的。您可以通过首先签署一些数据来获取私钥,因为 pkey_id 作为响应的一部分返回。然后签署你的 JWT。

我建议您从使用 Sign Blob API 切换到使用 SignJwt API。 SignJwt API 不需要您创建 JWT header.

IAM Service Account Credentials API

Method: projects.serviceAccounts.signJwt