Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Authentication 无法使用Python中的服务帐户密钥文件发布请求,获取';无效的IAP凭据:无法分析JWT'';401状态代码';_Authentication_Google App Engine_Google Cloud Platform_Python Requests_Service Accounts - Fatal编程技术网

Authentication 无法使用Python中的服务帐户密钥文件发布请求,获取';无效的IAP凭据:无法分析JWT'';401状态代码';

Authentication 无法使用Python中的服务帐户密钥文件发布请求,获取';无效的IAP凭据:无法分析JWT'';401状态代码';,authentication,google-app-engine,google-cloud-platform,python-requests,service-accounts,Authentication,Google App Engine,Google Cloud Platform,Python Requests,Service Accounts,我正试图向Google应用程序引擎服务发送一个POST请求,其中包含一个JSON正文和一个授权令牌。我正在从本地服务帐户密钥JSON文件生成访问令牌。下面的代码正在生成凭据,但最终授权被拒绝。我也尝试过不同的方法。甚至尝试在邮件头中使用承载令牌,或者甚至作为普通的cURL命令,在Postman中编写请求。但不管我怎么做,都会出现401身份验证错误。我需要确定问题是在我这边还是在服务的另一边。探索了所有可用的文档,但没有运气 from google.auth.transport import re

我正试图向Google应用程序引擎服务发送一个POST请求,其中包含一个JSON正文和一个授权令牌。我正在从本地服务帐户密钥JSON文件生成访问令牌。下面的代码正在生成凭据,但最终授权被拒绝。我也尝试过不同的方法。甚至尝试在邮件头中使用承载令牌,或者甚至作为普通的cURL命令,在Postman中编写请求。但不管我怎么做,都会出现401身份验证错误。我需要确定问题是在我这边还是在服务的另一边。探索了所有可用的文档,但没有运气

from google.auth.transport import requests
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession

CREDENTIAL_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
CREDENTIALS_KEY_PATH = 'my-local-service-account-key-file.json'

#the example service url I am trying to hit with requests
url = 'https://test.appspot.com/submit'

headers = {"Content-Type": "application/json"}

#example data I am sending with the request body
payload = {
  "key1": "value 1",
  "key2": "value 2"
}


credentials = service_account.Credentials.from_service_account_file(
                    CREDENTIALS_KEY_PATH,
                    scopes=CREDENTIAL_SCOPES
                    )

credentials.refresh(requests.Request())

authed_session = AuthorizedSession(credentials)

response = authed_session.request('POST',
                                  url,
                                  headers=headers,
                                  data=payload
                                )

#adding some debug lines for your help
print(response.text)
print(response.status_code)
print(response.headers)
获取输出:

Invalid IAP credentials: Unable to parse JWT
401
{'X-Goog-IAP-Generated-Response': 'true', 'Date': 'Mon, 03 May 2021 06:52:11 GMT', 'Content-Type': 'text/html', 'Server': 'Google Frontend', 'Content-Length': '44', 'Alt-Svc': 'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"'}
IAP希望在
授权
头中有
JWT(OpenID Connect(OIDC))令牌
,而您的方法将在
授权
头中附加访问令牌。请看下面的代码片段,向IAP安全资源发出请求

您的代码需要如下所示:

from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests


def make_iap_request(url, client_id, method='GET', **kwargs):
    """Makes a request to an application protected by Identity-Aware Proxy.

    Args:
      url: The Identity-Aware Proxy-protected URL to fetch.
      client_id: The client ID used by Identity-Aware Proxy.
      method: The request method to use
              ('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
      **kwargs: Any of the parameters defined for the request function:
                https://github.com/requests/requests/blob/master/requests/api.py
                If no timeout is provided, it is set to 90 by default.

    Returns:
      The page body, or raises an exception if the page couldn't be retrieved.
    """
    # Set the default timeout, if missing
    if 'timeout' not in kwargs:
        kwargs['timeout'] = 90

    # Obtain an OpenID Connect (OIDC) token from metadata server or using service
    # account.
    open_id_connect_token = id_token.fetch_id_token(Request(), client_id)

    # Fetch the Identity-Aware Proxy-protected URL, including an
    # Authorization header containing "Bearer " followed by a
    # Google-issued OpenID Connect token for the service account.
    resp = requests.request(
        method, url,
        headers={'Authorization': 'Bearer {}'.format(
            open_id_connect_token)}, **kwargs)
    if resp.status_code == 403:
        raise Exception('Service account does not have permission to '
                        'access the IAP-protected application.')
    elif resp.status_code != 200:
        raise Exception(
            'Bad response from application: {!r} / {!r} / {!r}'.format(
                resp.status_code, resp.headers, resp.text))
    else:
        return resp.text
注意:上面的方法使用隐式凭据,可以通过运行以下命令进行设置:
export GOOGLE\u APPLICATION\u credentials=my local service account key file.json
,在环境中设置服务帐户的路径,然后从同一终端运行python代码


查看更多信息。

我设置了
GOOGLE\u应用程序\u凭据
&调用了如下函数:在同一个终端上。获取错误:
无效IAP凭据:JWT访问群体与此应用程序不匹配('aud'声明(1075057…)与预期值(459957645727-m8ksv…u2q85knaqjg.apps.googleusercontent.com))不匹配作为请求响应。该服务与我的任何GCP项目都没有关联,我从.json密钥文件获取客户机ID。我遗漏了什么吗?您似乎输入了错误的客户端ID。客户端ID是IAP安全资源的OAuth客户端ID。您可以在错误消息中找到客户端ID作为预期值。它应该看起来像
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
。您还可以在
api&Services部分>Credentials>oauth2.0客户机ID中找到客户机ID
您不能使用用户凭据执行fetch\u ID\u令牌。因此,命令
gcloud auth application default login
在此环境中不可用context@guillaumeblaquiere,谢谢你的意见!我正在相应地编辑答案。