这个问题与Google任务无法对云运行进行身份验证非常相似,但我没有使用自己的域。我正在使用云运行域本身。
我遵循了以下两个教程(两者都有点类似):
https://cloud.google.com/run/docs/triggering/using-tasks
https://cloud.google.com/tasks/docs/creating-http-target-tasks
我不确定是否有更多的教程,我错过了,但下面是完整的场景。
我有一些基于Django REST的API运行在Google上,它们是公开的。此外,我可以在没有任何问题的情况下使用它们(尽管随后需要身份验证)。
我已经创建了一个Google任务队列,我使用以下代码将任务发送给它
class QueueTaskMixin:
def send_task(self, payload=None):
url = 'https://my-public-cloud-run-app.a.run.app/api/conversation_types/'
client = tasks_v2.CloudTasksClient(credentials=credentials)
# `credentials` above belongs to a service account which have all sort of accesses
# Cloud SQL Admin
# Cloud SQL Client
# Cloud SQL Editor
# Cloud Tasks Admin
# Cloud Tasks Task Runner
# Service Account Token Creator
# Service Account User
# Cloud Run Admin
# Cloud Run Invoker
# Cloud Run Service Agent
# Storage Admin
parent = client.queue_path(
project=settings.GS_PROJECT_ID,
location=settings.GS_Q_REGION,
queue=settings.GS_Q_NAME)
task = {
'http_request':
{
'headers': {
'Content-type': 'application/json',
},
'http_method': tasks_v2.HttpMethod.POST,
'url': url,
'oidc_token': {
'service_account_email': settings.GS_Q_IAM_EMAIL,
# GS_Q_IAM_EMAIL is a another Service account that has
# Cloud Tasks Enqueuer
# Service Account User
# Cloud Run Invoker
}
}
}
if payload:
if isinstance(payload, dict):
payload = json.dumps(payload)
converted_payload = payload.encode()
task['http_request']['body'] = converted_payload
response = client.create_task(
request={'parent': parent, 'task': task}
)
print('Created task {}'.format(response.name))现在我得到了PERMISSION_DENIED(7): HTTP status code 403错误。我的API日志显示了相同的内容:
"POST /api/conversation_types/ HTTP/1.1" 403 58 "-" "Google-Cloud-Tasks"
Forbidden: /api/conversation_types/现在我不确定的是,这个403错误是否由
关于这些文档,我不确定我必须在哪里提供API用户名/密码/JWT令牌。文件上说:
To authenticate between Cloud Tasks and an HTTP Target handler, Cloud Tasks creates a header token. This token is based on the credentials in the Cloud Tasks Enqueuer service account, identified by its email address.是否需要以用户身份将此服务帐户电子邮件地址添加到我的API中?我是用oidc还是oauth
任何评论或回答都非常感谢。
更新1 -在从中删除auth之后,云任务能够成功地调用。那么现在我如何使用云任务来运行我的API呢?
更新2 -尝试使用OAuthToken并获得错误
400 Invalid url for HttpRequest.oauth_token. The hostname in the url must end with ".googleapis.com"看来只能使用OIDC令牌了。
更新3 - Google说:
OIDC tokens are signed JSON Web Tokens (JWT) and are used primarily to assert identity and not to provide any implicit authorization against a resource, unlike OAuth tokens, which do provide access.这是否意味着OIDC令牌不能用于授权?因为我这里有授权错误。不能使用OIDC,不能使用OAuth,那么使用什么呢?
根据@johnhanley的注释,更新4,我已经更新了API以接受Bearer令牌进行身份验证。但是,即使我的API正确地获得了令牌,它也无法授权它,并且会产生invalid token错误(我使用curl命令验证了它)。在令牌格式不正确或令牌不正确的两种情况下,API只是返回403禁止的错误)。
任何人都可以告诉用户如何将密码(我可以在API中为服务帐户用户电子邮件生成密码)给服务帐户,以便使用该密码和电子邮件ID作为用户名,OIDC可以生成一个令牌并使用它进行身份验证。还是我走错方向了?
发布于 2021-08-23 10:33:32
检查云任务服务代理(service-[project-number]@gcp-sa-cloudtasks.iam.gserviceaccount.com)在您的IAM管理控制台页面中的存在,并授予他roles/iam.serviceAccountTokenCreator角色。
发布于 2021-09-02 06:13:29
不要关闭身份验证,它确实有效。下面是以bash命令和注释的形式来解释这些步骤的一些步骤
设置一些变量
PROJECT_ID='my-gcp-project-123'
TASK_ENQUER_SVC_ACCOUNT='tasks-creator-svc'
TASKS_SRV_ACCOUNT='cloud-tasks-svc'
CLOUD_RUN_SRV_ACCOUNT='cloud-run-svc'
GPC_REGION='australia-southeast1'创建云任务队列
gcloud tasks queues create my-task-queue创建一个用于发送任务的服务帐户--您需要cloudtasks.enqueuer和serviceAccountUser
gcloud iam service-accounts create $TASK_ENQUER_SVC_ACCOUNT \
--display-name "Service account for sending cloud tasks"
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member \
serviceAccount:$TASK_ENQUER_SVC_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--role "roles/logging.logWriter"
# cloudtasks.enqueuer role is needed to create tasks
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member \
serviceAccount:$TASK_ENQUER_SVC_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--role "roles/cloudtasks.enqueuer"
# service account user role is needed for permission iam.serviceAccounts.actAs
# so a task can be generated as service account $TASKS_SRV_ACCOUNT
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member \
serviceAccount:$TASK_ENQUER_SVC_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--role "roles/iam.serviceAccountUser"创建运行云运行服务的服务帐户
gcloud iam service-accounts create $CLOUD_RUN_SRV_ACCOUNT \
--display-name "Service account for running cloud run service"
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member \
serviceAccount:$CLOUD_RUN_SRV_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--role "roles/logging.logWriter"创建云任务将使用的服务帐户-不需要特殊权限。
gcloud iam service-accounts create $TASKS_SRV_ACCOUNT \
--display-name "Service account for the cloud-tasks"
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member \
serviceAccount:$TASKS_SRV_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--role "roles/logging.logWriter"使用ingress=all和no-allow-unauthenticated部署云运行服务
云任务不使用无服务器的VPC连接器,所以入口需要全部。
gcloud run deploy my-cloud-run-service \
--image=us.gcr.io/${PROJECT_ID}/my-docker-image \
--concurrency=1 \
--cpu=2 \
--memory=250Mi \
--max-instances=10 \
--platform=managed \
--region=$GPC_REGION \
--no-allow-unauthenticated \
--port=8080 \
--service-account=$CLOUD_RUN_SRV_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--ingress=all \
--project=${PROJECT_ID}现在必须授予TASKS_SRV_ACCOUNT调用云运行目标服务的权限
gcloud run services add-iam-policy-binding my-cloud-run-service \
--member=serviceAccount:$TASKS_SRV_ACCOUNT@${PROJECT_ID}.iam.gserviceaccount.com \
--role=roles/run.invoker \
--region=$GPC_REGION然后,您可以按照本步骤https://cloud.google.com/tasks/docs/creating-http-target-tasks#token上的指令发送带有身份验证令牌的云任务。
service_account_email参数是上面创建的TASKS_SRV_ACCOUNT
https://stackoverflow.com/questions/68879202
复制相似问题