GCP - 将服务帐户模拟为用户
GCP - Impersonate service account as a user
我想允许用户模拟一个服务帐户来对一个较长的 运行 进程进行操作。
但是,所有代码示例都说明了一个服务帐户模拟另一个服务帐户。
用户可以直接冒充服务帐号吗?如果是,怎么做?
我正在关注 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)
与其尝试从用户帐户模拟服务帐户,不如授予用户创建服务帐户 OAuth 访问令牌的权限。
在服务帐户上授予用户 roles/iam.serviceAccountTokenCreator
角色。
调用 API generateAccessToken
从服务帐户创建访问令牌。
projects.serviceAccounts.generateAccessToken
一个简单的 HTTP POST 请求将 return 一个访问令牌。使用服务帐户电子邮件地址修改以下请求。
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE-ACCOUNT-NAME@PROJECTID.iam.gserviceaccount.com:generateAccessToken
请求Body:
{
"delegates": [],
"scope": [
"https://www.googleapis.com/auth/cloud-platform"
],
"lifetime": "3600s"
}
此 API 需要授权。在 HTTP 授权中包含用户的 OAuth 访问令牌 header.
Authorization: Bearer ACCESS_TOKEN
响应Body:
{
"accessToken": "eyJ0eXAifeA...NiK8i",
"expireTime": "2020-03-05T15:01:00.12345678Z"
}
是的,您可以从用户模拟到服务帐户。您只需确保您的用户对目标服务帐户具有 Service Account Token Creator 角色。
您需要通过以下方式明确授予它:
- Select在 IAM 和管理中创建服务帐户
- Select IAM
- Select 您的帐户和您自己作为上述角色(服务帐户令牌创建者)。
即使您是项目所有者,也无济于事。
请注意,申请权限可能需要 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)
我想允许用户模拟一个服务帐户来对一个较长的 运行 进程进行操作。 但是,所有代码示例都说明了一个服务帐户模拟另一个服务帐户。
用户可以直接冒充服务帐号吗?如果是,怎么做?
我正在关注 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)
与其尝试从用户帐户模拟服务帐户,不如授予用户创建服务帐户 OAuth 访问令牌的权限。
在服务帐户上授予用户 roles/iam.serviceAccountTokenCreator
角色。
调用 API generateAccessToken
从服务帐户创建访问令牌。
projects.serviceAccounts.generateAccessToken
一个简单的 HTTP POST 请求将 return 一个访问令牌。使用服务帐户电子邮件地址修改以下请求。
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE-ACCOUNT-NAME@PROJECTID.iam.gserviceaccount.com:generateAccessToken
请求Body:
{
"delegates": [],
"scope": [
"https://www.googleapis.com/auth/cloud-platform"
],
"lifetime": "3600s"
}
此 API 需要授权。在 HTTP 授权中包含用户的 OAuth 访问令牌 header.
Authorization: Bearer ACCESS_TOKEN
响应Body:
{
"accessToken": "eyJ0eXAifeA...NiK8i",
"expireTime": "2020-03-05T15:01:00.12345678Z"
}
是的,您可以从用户模拟到服务帐户。您只需确保您的用户对目标服务帐户具有 Service Account Token Creator 角色。 您需要通过以下方式明确授予它:
- Select在 IAM 和管理中创建服务帐户
- Select IAM
- Select 您的帐户和您自己作为上述角色(服务帐户令牌创建者)。
即使您是项目所有者,也无济于事。
请注意,申请权限可能需要 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)