【问题标题】:GCP - Impersonate service account as a userGCP - 将服务帐户模拟为用户
【发布时间】:2020-06-18 15:19:01
【问题描述】:

我希望允许用户模拟服务帐户来对长时间运行的进程进行操作。 但是,所有代码示例都说明了一个服务帐户模拟另一个服务帐户。

用户可以直接模拟服务帐号吗?如果有,怎么做?

我正在关注this example code

初始化无权访问列表存储桶的源凭据:

from google.oauth2 import service_acccount

target_scopes = [
    'https://www.googleapis.com/auth/devstorage.read_only']

source_credentials = (
    service_account.Credentials.from_service_account_file(
        '/path/to/svc_account.json',
        scopes=target_scopes))

现在使用源凭据获取凭据以模拟另一个服务帐户:

from google.auth import impersonated_credentials

target_credentials = impersonated_credentials.Credentials(
  source_credentials=source_credentials,
  target_principal='impersonated-account@_project_.iam.gserviceaccount.com',
  target_scopes = target_scopes,
  lifetime=500)

【问题讨论】:

  • 你的问题一分。你提到了一个长期运行的过程。用户或服务帐户访问令牌的最长时间为 3,600 秒(一小时)。您需要令牌用于哪种类型的流程?两种帐户类型具有相同的到期限制。
  • 进程长期运行,但由另一个谷歌产品处理,服务帐户只负责启动、停止或修改该进程。

标签: google-cloud-platform impersonation service-accounts google-iam google-cloud-iam


【解决方案1】:

与其尝试从用户帐户模拟服务帐户,不如授予用户创建服务帐户 OAuth 访问令牌的权限。

在服务帐户上授予用户roles/iam.serviceAccountTokenCreator 角色。

调用 API generateAccessToken 从服务帐户创建访问令牌。

projects.serviceAccounts.generateAccessToken

一个简单的 HTTP POST 请求将返回一个访问令牌。使用服务帐户电子邮件地址修改以下请求。

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE-ACCOUNT-NAME@PROJECTID.iam.gserviceaccount.com:generateAccessToken

请求正文:

{
  "delegates": [],
  "scope": [
      "https://www.googleapis.com/auth/cloud-platform"
  ],
  "lifetime": "3600s"
}

此 API 需要授权。在 HTTP 授权标头中包含用户的 OAuth 访问令牌。

Authorization: Bearer ACCESS_TOKEN

响应正文:

{
   "accessToken": "eyJ0eXAifeA...NiK8i",
   "expireTime": "2020-03-05T15:01:00.12345678Z"
}

【讨论】:

    【解决方案2】:

    是的,您可以从用户模拟到服务帐户。您只需确保您的用户具有目标服务帐户的Service Account Token Creator 角色。 您需要通过以下方式明确授予它:

    1. 在 IAM & Admin 中选择服务帐号
    2. 选择 IAM
    3. 选择您的帐户和您自己作为上述角色(服务帐户令牌创建者)。

    即使您是项目所有者,它也不会削减它。

    请注意,申请权限可能需要 1-2 分钟,因此如果您的代码错误:

    Unable to acquire impersonated credentials...

    确保您拥有上述权限,如果您最近刚刚添加,请休息一下,然后再试一次 :)

    代码几乎保持不变,这是来自文档的改编示例:

    import google.auth
    import google.auth.impersonated_credentials
    from google.cloud import storage
    
    
    target_scopes = [
        "https://www.googleapis.com/auth/devstorage.read_only"
    ]
    
    creds, pid = google.auth.default()
    print(f"Obtained default credentials for the project {pid}")
    tcreds = google.auth.impersonated_credentials.Credentials(
        source_credentials=creds,
        target_principal="<target service account email>",
        target_scopes=target_scopes,
    )
    
    client = storage.Client(credentials=tcreds)
    buckets = client.list_buckets(project=pid)
    for bucket in buckets:
        print(bucket.name)
    

    【讨论】:

    猜你喜欢
    • 2023-01-31
    • 2015-01-03
    • 2021-12-01
    • 2020-05-31
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多