我正在尝试使用官方 GCP Python 库和服务帐户凭据访问位于 IAP 后面的 (GKE) 应用程序。
代码是(取自https://cloud.google.com/iap/docs/samples/iap-make-request)
from google.oauth2 import id_token
from google.auth.transport.requests import Request
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
requests.request(
"GET",
"https://myapp.com",
headers={"Authorization": "Bearer {}".format(open_id_connect_token)}
)
其中
client_id
是 IAP 使用的 oauth 客户端 ID(类似于 8xxxxxxxxx.apps.googleusercontent.com
),GOOGLE_APPLICATION_CREDENTIALS
env var 指向服务帐户的 JSON 密钥文件。服务帐户具有适当的 IAM 权限来访问受 IAP 保护的应用程序。
我还使用
gcloud iap settings set SETTING_FILE --project=my-project
添加了以下 IAP 设置,其中 my-project
是 IAP 和应用程序所属的项目。
access_settings:
oauth_settings:
programmatic_clients: ["8xxxxxxxxx.apps.googleusercontent.com"]
我主要遵循这个指南: https://cloud.google.com/iap/docs/authentication-howto#authentication_from_a_service_account
我希望
request
发出的 HTTP 调用会产生 2xx 响应,或者至少到达应用程序。但是,它返回 401
并出现以下错误:
Invalid IAP credentials: Service Account doesn't match the authorized party for this application.
('sub' claim (1yyyyyyyyyyyyy) doesn't match expected value ([email protected]))
这里,值
1yyyyyyyyyyyyy
实际上是服务帐户 JSON 文件中的 client_id
属性。因此,它看起来像是由 Python 库生成的令牌(在幕后调用 https://oauth2.googleapis.com/token),具有 sub
和 azp
的意外组合。这是令牌的有效负载:
{
"aud": "8xxxxxxxxx.apps.googleusercontent.com",
"azp": "[email protected]",
"email": "[email protected]",
"email_verified": true,
"exp": 1696584237,
"iat": 1696580637,
"iss": "https://accounts.google.com",
"sub": "1yyyyyyyyyyyyy"
}
我一直在尝试以下方法,但结果没有改变:
client_id
添加到 access_settings.oauth_settings.programmatic_clients
配置中,但被 gcloud
拒绝。gcloud iap settings set SETTING_FILE
的调用中使用不同的标志,例如--resource-type
、--organization
或--service
有人知道如何获取IAP接受的服务账户的令牌吗?
我最近遇到了同样的问题,并且一直在尝试各种方法来使用令牌,但到目前为止没有任何效果。