Google 云端点 - Auth0 - "id_token verification failed: Invalid token signature"
Google Cloud Endpoints - Auth0 - "id_token verification failed: Invalid token signature"
我正在尝试使用 Google Cloud Endpoints 设置 Auth0。
我遵循了
的指示
- https://cloud.google.com/endpoints/docs/frameworks/python/quickstart-frameworks-python
- https://cloud.google.com/endpoints/docs/openapi-configuration
- https://cloud.google.com/endpoints/docs/authenticating-users
我想使用我已经从 Auth0 iOS SDK 创建的 Auth0 认证用户从我的 iOS 应用调用“http://10.50.10.31:8080/_ah/api/echo/v1/test/”。
let url = URL(string: "http://10.50.10.31:8080/_ah/api/echo/v1/test/")!
var request = URLRequest(url: url)
request.addValue("Bearer \(session.token.idToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(data)
print(response)
}
task.resume()
Swift 代码工作正常。 session.idToken 来自 Auth0 iOS 框架。
文件app.yaml是
runtime: python27
api_version: 1
threadsafe: true
env_variables:
# The following values are to be replaced by information from the output of
# 'gcloud service-management deploy swagger.json' command.
ENDPOINTS_SERVICE_NAME: echo-api.endpoints.duskmotion-2016.cloud.goog
ENDPOINTS_SERVICE_VERSION: 2017-02-16r0
builtins:
- appstats: on
- admin_redirect: on
- deferred: on
- remote_api: on
libraries:
- name: jinja2
version: "2.6"
- name: markupsafe
version: "0.15"
- name: pycrypto
version: "2.6.1"
- name: enum
version: "0.9.23"
- name: protorpc
version: "1.0"
- name: pytz
version: "2016.4"
- name: six
version: "1.9.0"
- name: ssl
version: "2.7.11"
- name: werkzeug
version: "0.11.10"
inbound_services:
- warmup
handlers:
- url: /favicon.ico
static_files: application/static/img/favicon.ico
upload: application/static/img/favicon.ico
- url: /robots.txt
static_files: application/static/robots.txt
upload: application/static/robots.txt
- url: /gae_mini_profiler/static
static_dir: lib/gae_mini_profiler/static
- url: /gae_mini_profiler/.*
script: lib.gae_mini_profiler.main.application
- url: /static
static_dir: application/static
- url: /admin/logout
script: run.application.app
secure: always
login: required
- url: /admin/.*
script: run.application.app
secure: always
login: admin
auth_fail_action: redirect
- url: /_ah/warmup
script: run.application.app
secure: always
- url: /_ah/.*
script: run.application.urls.api
- url: .*
script: run.application.app
secure: always
skip_files:
- ^(.*/)?#.*#$
- ^(.*/)?.*~$
- ^(.*/)?.*\.py[co]$
- ^(.*/)?.*/RCS/.*$
- ^(.*/)?.*\(dev\).tmpl
- ^(.*/)?\..*$
- ^(.*/)?setuptools/script \(dev\).tmpl$
文件main.py是
import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote
auth0_issuer = endpoints.Issuer(
issuer='https://duskmotion.auth0.com/',
jwks_uri='https://duskmotion.auth0.com/.well-known/jwks.json')
class EchoRequest(messages.Message):
content = messages.StringField(1)
class EchoResponse(messages.Message):
"""A proto Message that contains a simple string field."""
content = messages.StringField(1)
ECHO_RESOURCE = endpoints.ResourceContainer(
EchoRequest,
n=messages.IntegerField(2, default=1))
@endpoints.api(name='echo', version='v1', issuers={"auth0-jwk" : auth0_issuer})
class EchoApi(remote.Service):
@endpoints.method(
# This method takes a ResourceContainer defined above.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='test',
http_method='GET',
name='echo_test_get')
def echo_test_get(self, request):
# auth = request.headers.get('Authorization', None)
import logging
logging.info(request)
user = endpoints.get_current_user()
content = "Nothing"
if user:
content = "It is working"
import logging
logging.info(content)
if not user:
raise endpoints.UnauthorizedException
return EchoResponse(content=content)
api = endpoints.api_server([EchoApi])
生成 API 文件后,我手动添加了 "Security" "x-security" 和 "securityDefinitions".
文件 echov1openapi.json 看起来像
{
"basePath": "/_ah/api",
"consumes": [
"application/json"
],
"definitions": {
"ApplicationUrlsEchoResponse": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
}
},
"host": "echo-api.endpoints.duskmotion-2016.cloud.goog",
"info": {
"title": "echo",
"version": "v1"
},
"paths": {
"/echo/v1/test": {
"get": {
"operationId": "EchoApi_echoTestGet",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/ApplicationUrlsEchoResponse"
}
}
},
"security": [
{
"auth0_jwk": []
}
]
}
}
},
"produces": [
"application/json"
],
"schemes": [
"http"
],
"x-security": [{
"auth0_jwk": {
"audiences": [
"xxxxxxxxxxxxxxxxxx"
]
}
}],
"securityDefinitions": {
"auth0_jwk": {
"authorizationUrl": "https://duskmotion.auth0.com/authorize",
"flow": "implicit",
"type": "oauth2",
"x-issuer": "https://duskmotion.auth0.com/",
"x-jwks_uri": "https://duskmotion.auth0.com/.well-known/jwks.json"
}
},
"swagger": "2.0"
}
当我 运行 在本地 Google App Engine 开发服务器上时,我得到
DEBUG 2017-02-16 23:55:25,551 users_id_token.py:198] Checking for id_token.
DEBUG 2017-02-16 23:55:25,551 users_id_token.py:485] Loading certs from https://www.googleapis.com/service_accounts/v1/metadata/raw/federated-signon@system.gserviceaccount.com
DEBUG 2017-02-16 23:55:25,568 users_id_token.py:269] id_token verification failed: Invalid token signature
DEBUG 2017-02-16 23:55:25,569 users_id_token.py:209] Checking for oauth token.
DEBUG 2017-02-16 23:55:25,569 users_id_token.py:340] Fetching token info from https://www.googleapis.com/oauth2/v1/tokeninfo
ERROR 2017-02-16 23:55:25,840 users_id_token.py:349] Token info endpoint returned status 400: Invalid Value
调试线2和5来自我自己。
- 为什么调用 *.googleapis.com 端点而不是我的 *.auth0.com?
- 我在 .py 文件中的设置中缺少什么才能使其正常工作?
这是开发服务器上 Endpoints Frameworks 的一个已知问题,已在项目问题跟踪器中报告:3rd-party auth does not work with dev-server #55。
另请参阅相关 Google Groups thread 以了解正在进行的讨论。
我正在尝试使用 Google Cloud Endpoints 设置 Auth0。
我遵循了
的指示- https://cloud.google.com/endpoints/docs/frameworks/python/quickstart-frameworks-python
- https://cloud.google.com/endpoints/docs/openapi-configuration
- https://cloud.google.com/endpoints/docs/authenticating-users
我想使用我已经从 Auth0 iOS SDK 创建的 Auth0 认证用户从我的 iOS 应用调用“http://10.50.10.31:8080/_ah/api/echo/v1/test/”。
let url = URL(string: "http://10.50.10.31:8080/_ah/api/echo/v1/test/")!
var request = URLRequest(url: url)
request.addValue("Bearer \(session.token.idToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(data)
print(response)
}
task.resume()
Swift 代码工作正常。 session.idToken 来自 Auth0 iOS 框架。
文件app.yaml是
runtime: python27
api_version: 1
threadsafe: true
env_variables:
# The following values are to be replaced by information from the output of
# 'gcloud service-management deploy swagger.json' command.
ENDPOINTS_SERVICE_NAME: echo-api.endpoints.duskmotion-2016.cloud.goog
ENDPOINTS_SERVICE_VERSION: 2017-02-16r0
builtins:
- appstats: on
- admin_redirect: on
- deferred: on
- remote_api: on
libraries:
- name: jinja2
version: "2.6"
- name: markupsafe
version: "0.15"
- name: pycrypto
version: "2.6.1"
- name: enum
version: "0.9.23"
- name: protorpc
version: "1.0"
- name: pytz
version: "2016.4"
- name: six
version: "1.9.0"
- name: ssl
version: "2.7.11"
- name: werkzeug
version: "0.11.10"
inbound_services:
- warmup
handlers:
- url: /favicon.ico
static_files: application/static/img/favicon.ico
upload: application/static/img/favicon.ico
- url: /robots.txt
static_files: application/static/robots.txt
upload: application/static/robots.txt
- url: /gae_mini_profiler/static
static_dir: lib/gae_mini_profiler/static
- url: /gae_mini_profiler/.*
script: lib.gae_mini_profiler.main.application
- url: /static
static_dir: application/static
- url: /admin/logout
script: run.application.app
secure: always
login: required
- url: /admin/.*
script: run.application.app
secure: always
login: admin
auth_fail_action: redirect
- url: /_ah/warmup
script: run.application.app
secure: always
- url: /_ah/.*
script: run.application.urls.api
- url: .*
script: run.application.app
secure: always
skip_files:
- ^(.*/)?#.*#$
- ^(.*/)?.*~$
- ^(.*/)?.*\.py[co]$
- ^(.*/)?.*/RCS/.*$
- ^(.*/)?.*\(dev\).tmpl
- ^(.*/)?\..*$
- ^(.*/)?setuptools/script \(dev\).tmpl$
文件main.py是
import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote
auth0_issuer = endpoints.Issuer(
issuer='https://duskmotion.auth0.com/',
jwks_uri='https://duskmotion.auth0.com/.well-known/jwks.json')
class EchoRequest(messages.Message):
content = messages.StringField(1)
class EchoResponse(messages.Message):
"""A proto Message that contains a simple string field."""
content = messages.StringField(1)
ECHO_RESOURCE = endpoints.ResourceContainer(
EchoRequest,
n=messages.IntegerField(2, default=1))
@endpoints.api(name='echo', version='v1', issuers={"auth0-jwk" : auth0_issuer})
class EchoApi(remote.Service):
@endpoints.method(
# This method takes a ResourceContainer defined above.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='test',
http_method='GET',
name='echo_test_get')
def echo_test_get(self, request):
# auth = request.headers.get('Authorization', None)
import logging
logging.info(request)
user = endpoints.get_current_user()
content = "Nothing"
if user:
content = "It is working"
import logging
logging.info(content)
if not user:
raise endpoints.UnauthorizedException
return EchoResponse(content=content)
api = endpoints.api_server([EchoApi])
生成 API 文件后,我手动添加了 "Security" "x-security" 和 "securityDefinitions".
文件 echov1openapi.json 看起来像
{
"basePath": "/_ah/api",
"consumes": [
"application/json"
],
"definitions": {
"ApplicationUrlsEchoResponse": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
}
},
"host": "echo-api.endpoints.duskmotion-2016.cloud.goog",
"info": {
"title": "echo",
"version": "v1"
},
"paths": {
"/echo/v1/test": {
"get": {
"operationId": "EchoApi_echoTestGet",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/ApplicationUrlsEchoResponse"
}
}
},
"security": [
{
"auth0_jwk": []
}
]
}
}
},
"produces": [
"application/json"
],
"schemes": [
"http"
],
"x-security": [{
"auth0_jwk": {
"audiences": [
"xxxxxxxxxxxxxxxxxx"
]
}
}],
"securityDefinitions": {
"auth0_jwk": {
"authorizationUrl": "https://duskmotion.auth0.com/authorize",
"flow": "implicit",
"type": "oauth2",
"x-issuer": "https://duskmotion.auth0.com/",
"x-jwks_uri": "https://duskmotion.auth0.com/.well-known/jwks.json"
}
},
"swagger": "2.0"
}
当我 运行 在本地 Google App Engine 开发服务器上时,我得到
DEBUG 2017-02-16 23:55:25,551 users_id_token.py:198] Checking for id_token.
DEBUG 2017-02-16 23:55:25,551 users_id_token.py:485] Loading certs from https://www.googleapis.com/service_accounts/v1/metadata/raw/federated-signon@system.gserviceaccount.com
DEBUG 2017-02-16 23:55:25,568 users_id_token.py:269] id_token verification failed: Invalid token signature
DEBUG 2017-02-16 23:55:25,569 users_id_token.py:209] Checking for oauth token.
DEBUG 2017-02-16 23:55:25,569 users_id_token.py:340] Fetching token info from https://www.googleapis.com/oauth2/v1/tokeninfo
ERROR 2017-02-16 23:55:25,840 users_id_token.py:349] Token info endpoint returned status 400: Invalid Value
调试线2和5来自我自己。
- 为什么调用 *.googleapis.com 端点而不是我的 *.auth0.com?
- 我在 .py 文件中的设置中缺少什么才能使其正常工作?
这是开发服务器上 Endpoints Frameworks 的一个已知问题,已在项目问题跟踪器中报告:3rd-party auth does not work with dev-server #55。
另请参阅相关 Google Groups thread 以了解正在进行的讨论。