我在Google标准环境中使用使用Python的云终结点框架来提供API。
据我所知,我应该能够使用端点框架中的python装饰器和endpointscfg.py命令行工具结合使用Auth0自动设置基于令牌的身份验证;endpointscfg.py命令行自动创建用于配置Google代理的openapi.json文件。
下面是我的API装饰器的一个示例,该API会回显内容:
# # [START echo_api]
@endpoints.api(
name='echo',
version=_VERSION,
api_key_required=True,
audiences={'auth0': ['https://echo.<my-project>.appspot.com/_ah/api/echo/v1/echo']},
issuers={'auth0': endpoints.Issuer(
'https://<my-project>.auth0.com',
'https://<my-project>.auth0.com/.well-known/jwks.json')}
)
class EchoApi(remote.Service):
...当我运行endpointscfg.py命令行工具时,我在我的openapi.json文件中得到了一些看起来很好的东西:
"paths": {
"/echo/v1/echo": {
"post": {
"operationId": "EchoApi_echo",
"parameters": [
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/MainEchoRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
},
"security": [
{
"api_key": [],
"auth0_jwt": []
}
]
}
}
"securityDefinitions": {
"api_key": {
"in": "query",
"name": "key",
"type": "apiKey"
},
"auth0_jwt": {
"authorizationUrl": "https://<my-project>.auth0.com/authorize",
"flow": "implicit",
"type": "oauth2",
"x-google-issuer": "https://<my-project>.auth0.com",
"x-google-jwks_uri": "https://<my-project>.auth0.com/.well-known/jwks.json",
"x-google-audiences": "https://echo.<my-project>.appspot.com/_ah/api/echo/v1/echo"
}
}因此,问题在于,如果没有令牌存在或令牌无效,则此设置似乎什么也不做,也不检查传入令牌以防止访问。
我已经能够使用python库在API回送函数中设置承载令牌的手动处理(如果没有很好的处理,很抱歉,但我只是在测试,欢迎评论):
authorization_header = self.request_state.headers.get('authorization')
if authorization_header is not None:
if authorization_header.startswith('Bearer '):
access_token = authorization_header[7:]
logging.info(access_token)
else:
logging.error("Authorization header did not start with 'Bearer '!")
raise endpoints.UnauthorizedException(
"Authentication failed (improperly formatted authorization header).")
else:
logging.error("Authorization header did not start with 'Bearer '!")
raise endpoints.UnauthorizedException("Authentication failed (bearer token not found).")
r = urlfetch.fetch(_JWKS_URL)
jwks_content = json.loads(r.content)
keys = jwks_content['keys']
public_key = jwk.construct(keys[0])
logging.info(public_key)
message, encoded_signature = str(access_token).rsplit('.', 1)
# decode the signature
decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
# verify the signature
if not public_key.verify(message.encode("utf8"), decoded_signature):
logging.warning('Signature verification failed')
raise endpoints.UnauthorizedException("Authentication failed (invalid signature).")
else:
logging.info('Signature successfully verified')
claims = jwt.get_unverified_claims(access_token)
# additionally we can verify the token expiration
if time.time() > claims['exp']:
logging.warning('Token is expired')
raise endpoints.UnauthorizedException("Authentication failed (token expired).")
# and the Audience (use claims['client_id'] if verifying an access token)
if claims['aud'] != _APP_CLIENT_ID:
logging.warning('Token was not issued for this audience')
raise endpoints.UnauthorizedException("Authentication failed (incorrect audience).")
# now we can use the claims
logging.info(claims)这段代码可以工作,但我认为设置装饰器和配置openapi.json文件的全部目的是将这些检查卸载到代理,这样只有有效的令牌才能命中我的代码。
我做错了什么?
更新:--可能需要在代码中签入endpoints.get_current_user()来控制访问。然而,我刚刚在日志中注意到以下几点:
Cannot decode and verify the auth token. The backend will not be able to retrieve user info (/base/data/home/apps/e~<my-project>/echo:alpha23.414400469228485401/lib/endpoints_management/control/wsgi.py:643)
Traceback (most recent call last):
File "/base/data/home/apps/e~<my-project>/echo:alpha23.414400469228485401/lib/endpoints_management/control/wsgi.py", line 640, in __call__
service_name)
File "/base/data/home/apps/e~<my-project>/echo:alpha23.414400469228485401/lib/endpoints_management/auth/tokens.py", line 75, in authenticate
error)
UnauthenticatedException: (u'Cannot decode the auth token', UnauthenticatedException(u'Cannot find the `jwks_uri` for issuer https://<my-project>.auth0.com/: either the issuer is unknown or the OpenID discovery failed',))不过,我认为一切都配置好了。知道为什么“jwks_uri”不能被找到,尽管openapi.json文件中的路径是正确的?
发布于 2018-12-04 18:45:39
我现在是这些框架的维护者。你确实需要检查endpoints.get_current_user()来控制访问,是的。我正在开发一个功能,让这个功能变得更简单。
至于那个UnauthenticatedException,你可以忽略它。这来自于“管理框架”,它试图检查auth令牌,尽管它不涉及框架的oauth安全性(只有api密钥安全性)。
https://stackoverflow.com/questions/53581223
复制相似问题