英文:
Error 401 Unauthorized when invoking Cloud Function despite granting roles
问题
我一直在尝试自己解决这个问题,但一直没有成功。我创建了一个简单的云函数(第一代),应该返回消息“hello world”。
def hello_world(request):
return 'Hello World'
我将其命名为function-test-3并进行部署。然后,我创建了另一个函数,我希望从该函数中调用此函数,并通过请求调用中的标头传递所需的授权参数。
import google.oauth2.id_token
import google.auth.transport.requests
import requests
endpoint = 'https://us-central1-sport-app-395020.cloudfunctions.net/function-test-3'
def make_authorized_get_request(endpoint):
auth_req = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(auth_req, endpoint)
header_1 = {'Authorization':'Bearer '+id_token}
response = requests.get(url=endpoint,headers=header_1)
return str(response.content)
然后我收到401错误。我不知道还能做什么,我已经给予调用函数和被调用函数的服务帐号所有者、函数调用者、函数管理员和其他角色。这似乎没有解决问题。
如果我通过命令行界面打印出一个id令牌,并将字符串直接粘贴到请求的标头中,那么它可以工作。
我希望能够在没有JSON文件的情况下使其工作。因为我看到有些方法使用了JSON文件。
非常感谢任何想法。
编辑1:
新的服务帐号ID:
new-service-account@sport-app-395020.iam.gserviceaccount.com
gcloud functions describe function-test-3
availableMemoryMb: 256
buildId: d638badd-4a78-41f7-bb95-9a7c97561e0b
buildName: projects/445319123164/locations/us-central1/builds/d638badd-4a78-41f7-bb95-9a7c97561e0b
dockerRegistry: CONTAINER_REGISTRY
entryPoint: hello_world
httpsTrigger:
securityLevel: SECURE_OPTIONAL
url: https://us-central1-sport-app-395020.cloudfunctions.net/function-test-3
ingressSettings: ALLOW_ALL
labels:
deployment-tool: console-cloud
maxInstances: 3000
name: projects/sport-app-395020/locations/us-central1/functions/function-test-3
runtime: python310
serviceAccountEmail: new-service-account@sport-app-395020.iam.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-890291164480.us-central1.cloudfunctions.appspot.com/d00981be-b7cb-42b9-b443-85b7d1f0c29b.zip
status: ACTIVE
timeout: 60s
updateTime: '2023-08-09T01:11:03.263Z'
versionId: '3'
gcloud functions get-iam-policy function-test-3
bindings:
- members:
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
role: roles/cloudfunctions.admin
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
- members:
- serviceAccount:new-service-account@sport-app-395020.iam.gserviceaccount.com
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
role: roles/cloudfunctions.invoker
etag: BwYCcvpm7fc=
version: 1
gcloud functions describe doom-function-2
availableMemoryMb: 256
buildId: 669735af-ecb6-47de-b57b-a01119eed5b7
buildName: projects/445319123164/locations/us-central1/builds/669735af-ecb6-47de-b57b-a01119eed5b7
dockerRegistry: CONTAINER_REGISTRY
entryPoint: make_authorized_get_request
httpsTrigger:
securityLevel: SECURE_OPTIONAL
url: https://us-central1-sport-app-395020.cloudfunctions.net/doom-function-2
ingressSettings: ALLOW_ALL
labels:
deployment-tool: console-cloud
maxInstances: 3000
name: projects/sport-app-395020/locations/us-central1/functions/doom-function-2
runtime: python310
serviceAccountEmail: new-service-account@sport-app-395020.iam.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-890291164480.us-central1.cloudfunctions.appspot.com/c1312040-cb2c-4532-ad15-c33d637bb8d3.zip
status: ACTIVE
timeout: 60s
updateTime: '2023-08-09T01:08:10.996Z'
versionId: '29'
gcloud functions get-iam-policy doom-function-2
bindings:
- members:
- allUsers
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
role: roles/cloudfunctions.invoker
etag: BwYCYOllrBQ=
version: 1
实际错误消息:
Error: Unauthorized
Your client does not have permission to the requested URL function-test-3
我在jwt解码器中查看了令牌,它是有效的令牌,但无法工作,以下是其内容:
{
"header":
{
"alg":"RS256",
"kid":"911e39e27928ae9f1e9d1e21646de92d19351b44",
"typ":"JWT"
}
"payload":
{
"aud":"<Request 'http://us-central1-sport-app-395020.cloudfunctions.net/' [GET]>",
"azp":"113939113937084571622",
"email":"new-service-account@sport-app-395020.iam.gserviceaccount.com",
"email_verified":true,
"exp":1691553146,
"iat":1691549546,
"iss":"https://accounts.google.com",
"sub":"113939113937084571622"
}
}
英文:
I have been trying to solve this on my own but have not been able to do it.
I made a simple cloud function (1st gen) that should give the message "hello world"
def hello_world(request):
return 'Hello World'
I name it function-test-3 and deploy.
Then I made another function from which I want to invoke this function and pass required authorization parameters through headers in a requests call.
import google.oauth2.id_token
import google.auth.transport.requests
import requests
endpoint = 'https://us-central1-sport-app-395020.cloudfunctions.net/function-test-3'
def make_authorized_get_request(endpoint):
auth_req = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(auth_req, endpoint)
header_1 = {'Authorization':'Bearer '+id_token}
response = requests.get(url=endpoint,headers=header_1)
return str(response.content)
Then I get 401 error. I don't know what else to do, I have given owner, function invoker, function admin, and a plethora of other roles to the service account that has to invoke the functions, both in the called function and the caller one. This does not seem to solve the problem.
If I print an id token through the cli and literally paste the string in the header of the request, then it works.
I would like this to work without a json file. Because I have seen some methods that use that.
Any ideas would be greatly appreciated.
Edit 1:
New service account id:
new-service-account@sport-app-395020.iam.gserviceaccount.com
gcloud functions describe function-test-3
availableMemoryMb: 256
buildId: d638badd-4a78-41f7-bb95-9a7c97561e0b
buildName: projects/445319123164/locations/us-central1/builds/d638badd-4a78-41f7-bb95-9a7c97561e0b
dockerRegistry: CONTAINER_REGISTRY
entryPoint: hello_world
httpsTrigger:
securityLevel: SECURE_OPTIONAL
url: https://us-central1-sport-app-395020.cloudfunctions.net/function-test-3
ingressSettings: ALLOW_ALL
labels:
deployment-tool: console-cloud
maxInstances: 3000
name: projects/sport-app-395020/locations/us-central1/functions/function-test-3
runtime: python310
serviceAccountEmail: new-service-account@sport-app-395020.iam.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-890291164480.us-central1.cloudfunctions.appspot.com/d00981be-b7cb-42b9-b443-85b7d1f0c29b.zip
status: ACTIVE
timeout: 60s
updateTime: '2023-08-09T01:11:03.263Z'
versionId: '3'
gcloud functions get-iam-policy function-test-3
bindings:
- members:
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
role: roles/cloudfunctions.admin
- members:
- serviceAccount:new-service-account@sport-app-395020.iam.gserviceaccount.com
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
role: roles/cloudfunctions.invoker
etag: BwYCcvpm7fc=
version: 1
gcloud functions describe doom-function-2
availableMemoryMb: 256
buildId: 669735af-ecb6-47de-b57b-a01119eed5b7
buildName: projects/445319123164/locations/us-central1/builds/669735af-ecb6-47de-b57b-a01119eed5b7
dockerRegistry: CONTAINER_REGISTRY
entryPoint: make_authorized_get_request
httpsTrigger:
securityLevel: SECURE_OPTIONAL
url: https://us-central1-sport-app-395020.cloudfunctions.net/doom-function-2
ingressSettings: ALLOW_ALL
labels:
deployment-tool: console-cloud
maxInstances: 3000
name: projects/sport-app-395020/locations/us-central1/functions/doom-function-2
runtime: python310
serviceAccountEmail: new-service-account@sport-app-395020.iam.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-890291164480.us-central1.cloudfunctions.appspot.com/c1312040-cb2c-4532-ad15-c33d637bb8d3.zip
status: ACTIVE
timeout: 60s
updateTime: '2023-08-09T01:08:10.996Z'
versionId: '29'
gcloud functions get-iam-policy doom-function-2
bindings:
- members:
- allUsers
- serviceAccount:sport-app-395020@appspot.gserviceaccount.com
role: roles/cloudfunctions.invoker
etag: BwYCYOllrBQ=
version: 1
Actual error message:
Error: Unauthorized
Your client does not have permission to the requested URL function-test-3
I looked the token before in jwt decoder and it is a valid token, though it does not work, this is its content
{
"header":
{
"alg":"RS256"
"kid":"911e39e27928ae9f1e9d1e21646de92d19351b44"
"typ":"JWT"
}
"payload":
{
"aud":"<Request 'http://us-central1-sport-app-395020.cloudfunctions.net/' [GET]>"
"azp":"113939113937084571622"
"email":"new-service-account@sport-app-395020.iam.gserviceaccount.com"
"email_verified":true
"exp":1691553146
"iat":1691549546
"iss":"https://accounts.google.com"
"sub":"113939113937084571622"
}
}
答案1
得分: 1
1)创建一个新的服务账号。不要为其分配任何角色。记下邮箱地址。
2)进入Google Cloud控制台GUI。进入Cloud Functions。点击函数名称为function-test-3的函数。
3)点击“权限”选项卡。
4)点击“授予访问权限”。输入新服务账号的邮箱地址。选择Cloud Functions Invoker角色并保存。现在已经授权了该服务账号。
5)进入将要调用function-test-3的其他函数。
6)点击“编辑并重新部署”。
7)将运行时服务账号更改为新的服务账号。
英文:
- Create a new service account. Do not assign it any roles. Make note of the email address.
- Go to the Google Cloud Console GUI. Go to Cloud Functions. Click on the function name function-test-3.
- Click on the PERMISSIONS tab.
- Click GRANT ACCESS. Enter the email address of the new service account. Select Cloud Functions Invoker role and save. You have now authorized the service account.
- Go to the other function that will be calling function-test-3.
- Click EDIT AND REDPLOY.
- Change the Runtime Service Account to the new service account.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论