Bap*_*les 3 python google-cloud-platform google-cloud-python google-iap
我希望能够使用开发环境上的用户默认凭据以编程方式为Iap生成一个ID令牌(即,我自己的装有Google Cloud SDK并登录的笔记本电脑)。
遵循文档时,我设法使用服务帐户文件生成了授权令牌。
在google.auth.default个人计算机上使用时,我可以看到type的凭据google.oauth2.credentials.Credentials带有refresh_token。我想用它,因为它是在做卷曲生成令牌文档下 
 Authenticating from a desktop app -> Accessing the application,但我不能使它工作。有人知道是否可以通过这种方式进行身份验证吗?
如Matthew所述,用于获取刷新令牌的Client ID项目应与IAP Client ID项目匹配。Gcloud使用客户端ID和中定义的密码path_to/google-cloud-sdk/lib/googlecloudsdk/api_lib/auth/util.py作为默认凭据(DEFAULT_CREDENTIALS_DEFAULT_CLIENT_ID和DEFAULT_CREDENTIALS_DEFAULT_CLIENT_SECRET)。正因为如此,你不能使用刷新令牌从google.auth.default()没有util.py改变,作为一种尝试,以获得ID令牌将失败:
{
 "error": "invalid_audience",
 "error_description": "The audience client and the client need to be in the same project."
}
Run Code Online (Sandbox Code Playgroud)
您的选择是:
这两个选项的示例代码:
import google.auth
import requests
import json
from webbrowser import open_new_tab
from time import sleep
# use gcloud app default credentials if gcloud's util.py is patched
def id_token_from_default_creds(audience): 
    cred, proj = google.auth.default()
    # data necessary for ID token
    client_id = cred.client_id
    client_secret= cred.client_secret
    refresh_token = str(cred.refresh_token)
    return id_token_from_refresh_token(client_id, client_secret, refresh_token, audience)
def id_token_from_refresh_token(client_id, client_secret, refresh_token, audience):
    oauth_token_base_URL = "https://www.googleapis.com/oauth2/v4/token"
    payload = {"client_id": client_id, "client_secret": client_secret,
                "refresh_token": refresh_token, "grant_type": "refresh_token",
                "audience": audience}
    res = requests.post(oauth_token_base_URL, data=payload)
    return (str(json.loads(res.text)[u"id_token"]))
# obtain ID token for provided Client ID: get authorization code -> exchange for refresh token -> obtain and return ID token
def id_token_from_client_id(client_id, client_secret, audience):
    auth_code = get_auth_code(client_id)
    refresh_token = get_refresh_token_from_code(auth_code, client_id, client_secret)
    return id_token_from_refresh_token(client_id, client_secret, refresh_token, audience)
def get_auth_code(client_id):
    auth_url = "https://accounts.google.com/o/oauth2/v2/auth?client_id=%s&response_type=code&scope=openid%%20email&access_type=offline&redirect_uri=urn:ietf:wg:oauth:2.0:oob"%client_id
    open_new_tab(auth_url)
    sleep(1)
    return raw_input("Authorization code: ")
def get_refresh_token_from_code(auth_code, client_id, client_secret):
    oauth_token_base_URL = 'https://www.googleapis.com/oauth2/v4/token'
    payload = {"code": auth_code, "client_id": client_id, "client_secret": client_secret,
                "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", "grant_type": "authorization_code"}
    res = requests.post(oauth_token_base_URL, data=payload)
    return (str(json.loads(res.text)[u"refresh_token"]))
print("ID token from client ID: %s" % id_token_from_client_id("<Other client ID>", "<Other client secret>", "<IAP Client ID>")) # other client ID should be from the same project as IAP Client ID 
print("ID token from \"default\" credentials: %s" % id_token_from_default_creds("<IAP Client ID>"))
Run Code Online (Sandbox Code Playgroud)
        感谢您指出了这一点!如果我们有这方面的代码示例,我会很高兴,但正如您所发现的,至少对于 Python,我们用于服务帐户身份验证的代码示例不适用于用户帐户。
为您的客户端应用程序创建一个新的客户端 ID(与受 IAP 保护的应用程序位于同一项目中),并使用该客户端 ID 获取刷新令牌。您不能只使用应用程序默认凭据中的刷新令牌,因为这将具有错误的客户端 ID 和可能的范围。相反,您需要向应用程序添加“gcloud auth login”等功能并保留刷新令牌。
拥有刷新令牌后,当您的客户端应用程序想要访问 IAP 应用程序时:使用应用程序的 OAuth 客户端的客户端 ID 和密钥、刷新令牌POST 到https://www.googleapis.com/oauth2/v4/token,以及 IAP 客户端 ID。这将返回一个 OpenID Connect 令牌,该令牌对 IAP 进行身份验证的有效期为一小时。
这至少足以开始吗?