API网关自定义授权者:控制错误消息和代码

Kas*_*yap 6 java authentication http amazon-web-services aws-api-gateway

我有一个用于Gateway API的自定义授权者。我已经阅读了许多有关如何自定义错误消息和验证或授权错误时返回给最终用户的代码的文章。这似乎是最有用的

问题是API网关的行为与记录不符。

我的自定义授权者实现(python):

def lambda_handler(event, context):
    raise Exception('the sky is falling!')
Run Code Online (Sandbox Code Playgroud)

当我使用curl调用API时:

kash@Laptop$ date; curl -i -X GET -H "Authorization: Bearer 1234abcd`date +%s`" https://xxxx.execute-api.us-west-2.amazonaws.com/prod/ticket
Mon Jun  4 12:27:51 CDT 2018
HTTP/1.1 500 Internal Server Error
Date: Mon, 04 Jun 2018 17:27:53 GMT
Content-Type: application/json
Content-Length: 16
Connection: keep-alive
x-amzn-RequestId: 9cc6d7ce-681c-xxxx-8a4a-23a7616ba4a5
x-amzn-ErrorType: AuthorizerConfigurationException
x-amz-apigw-id: xxxx=

{"message":null}
kash@Laptop$ 
Run Code Online (Sandbox Code Playgroud)

我如何使其返回HTTP 4xx {"message": "the sky is falling!"}


用于调试:我通过我的API进入了网关响应,并从以下位置更新了“授权者配置错误(500)”的“正文映射模板”:

{"message":$context.error.messageString}
Run Code Online (Sandbox Code Playgroud)

对此:

{
      "errorMessage":"$errorMessage",
      "messageString":"$messageString",

      "context.errorMessage":"$context.errorMessage",
      "context.messageString":"$context.messageString",

      "context.error.errorMessage":"$context.error.errorMessage",
      "context.error.messageString":"$context.error.messageString",

      "context.authorizer.error.errorMessage":"$context.authorizer.error.errorMessage"
      "context.authorizer.error.errorMessage":"$context.authorizer.error.errorMessage"
      "context.authorizer.errorMessage":"$context.authorizer.errorMessage"
      "context.authorizer.messageString":"$context.authorizer.messageString"

      "type": "$context.error.responseType",
      "statusCode": "'404'",
      "stage": "$context.stage",
      "resourcePath": "$context.resourcePath",
      "stageVariables.a": "$stageVariables.a",

      "context.apiId": "$context.apiId",
      "context.authorizer.claims.property": "$context.authorizer.claims.property",
      "context.authorizer.principalId": "$context.authorizer.principalId",
      "context.authorizer.property": "$context.authorizer.property",
      "context.httpMethod": "$context.httpMethod",
      "context.error.message": "$context.error.message",
      "context.error.messageString": "$context.error.messageString",
      "context.error.responseType": "$context.error.responseType",
      "context.extendedRequestId": "$context.extendedRequestId",
      "context.identity.accountId": "$context.identity.accountId",
      "context.identity.apiKey": "$context.identity.apiKey",
      "context.identity.apiKeyId": "$context.identity.apiKeyId",
      "context.identity.caller": "$context.identity.caller",
      "context.identity.cognitoAuthenticationProvider": "$context.identity.cognitoAuthenticationProvider",
      "context.identity.cognitoAuthenticationType": "$context.identity.cognitoAuthenticationType",
      "context.identity.cognitoIdentityId": "$context.identity.cognitoIdentityId",
      "context.identity.cognitoIdentityPoolId": "$context.identity.cognitoIdentityPoolId",
      "context.identity.sourceIp": "$context.identity.sourceIp",
      "context.identity.user": "$context.identity.user",
      "context.identity.userAgent": "$context.identity.userAgent",
      "context.identity.userArn": "$context.identity.userArn",
      "context.integrationLatency": "$context.integrationLatency",
      "context.path": "$context.path",
      "context.protocol": "$context.protocol",
      "context.requestId": "$context.requestId",
      "context.requestTime": "$context.requestTime",
      "context.requestTimeEpoch": "$context.requestTimeEpoch",
      "context.resourceId": "$context.resourceId",
      "context.resourcePath": "$context.resourcePath",
      "context.responseLength": "$context.responseLength",
      "context.responseLatency": "$context.responseLatency",
      "context.status": "$context.status",
      "context.stage": "$context.stage"
 }
Run Code Online (Sandbox Code Playgroud)

响应是:

 {
      "errorMessage":"",
      "messageString":"",

      "context.errorMessage":"",
      "context.messageString":"",

      "context.error.errorMessage":"",
      "context.error.messageString":"null",

      "context.authorizer.error.errorMessage":""
      "context.authorizer.error.errorMessage":""
      "context.authorizer.errorMessage":""
      "context.authorizer.messageString":""

      "type": "AUTHORIZER_CONFIGURATION_ERROR",
      "statusCode": "'404'",
      "stage": "prod",
      "resourcePath": "/ticket",
      "stageVariables.a": "",

      "context.apiId": "xxxx",
      "context.authorizer.claims.property": "",
      "context.authorizer.principalId": "",
      "context.authorizer.property": "",
      "context.httpMethod": "GET",
      "context.error.message": "",
      "context.error.messageString": "null",
      "context.error.responseType": "AUTHORIZER_CONFIGURATION_ERROR",
      "context.extendedRequestId": "xxxx=",
      "context.identity.accountId": "",
      "context.identity.apiKey": "",
      "context.identity.apiKeyId": "",
      "context.identity.caller": "",
      "context.identity.cognitoAuthenticationProvider": "",
      "context.identity.cognitoAuthenticationType": "",
      "context.identity.cognitoIdentityId": "",
      "context.identity.cognitoIdentityPoolId": "",
      "context.identity.sourceIp": "xxx.244.xxx.2",
      "context.identity.user": "",
      "context.identity.userAgent": "curl/7.47.0",
      "context.identity.userArn": "",
      "context.integrationLatency": "",
      "context.path": "/prod/ticket",
      "context.protocol": "HTTP/1.1",
      "context.requestId": "57e2462d-681c-xxxx-7dd93186dc68",
      "context.requestTime": "04/Jun/2018:17:25:57 +0000",
      "context.requestTimeEpoch": "1528133157762",
      "context.resourceId": "pz9fb8",
      "context.resourcePath": "/ticket",
      "context.responseLength": "",
      "context.responseLatency": "",
      "context.status": "",
      "context.stage": "prod"


 }
Run Code Online (Sandbox Code Playgroud)

我读了:

以及AWS论坛上的更多内容。

Kas*_*yap 11

如果它可以帮助某人:

CA =定制授权者

  • 错误代码:AWS完全不允许CA实施指示发送回调用方的错误代码。
    • 如果CA返回的Auth Policy没有使用动作Allow的语句之一调用的资源/方法,则用户将收到403,内容类似于“未授权访问资源”
    • 如果CA返回的“身份验证策略中包含带有已调用的资源/方法的操作为“拒绝”的语句,则用户将收到403,例如“拒绝访问被明确拒绝”。
    • 如果CA引发的异常具有消息“未经授权”,则用户将收到消息为“未经授权”的401。
    • 如果CA引发任何其他消息异常,则用户将收到HTTP-500内部服务器错误(授权配置错误),并且呼叫被拒绝/未授权。
  • 错误消息:通过“网关响应”中的“正文映射”模板,仅允许静态控制。
    • 例如,您可以在“网关响应”中将“未授权[401]”的主体映射模板更新为“我的服务由于某些未知原因不喜欢您”,然后每当CA抛出“未授权”异常时,最终用户都会获得HTTP 401和“由于某种未知原因,我的服务不喜欢您”。
    • 同样,您也可以更新“访问被拒绝[403]”或“授权者配置错误[500]”。但是该消息是静态的,无法从CA实现中进行控制。
    • 这是不是可以有不同的消息401,如:
    • 401:由于令牌过期而未经授权。
    • 401:由于缺少范围,未经授权。

其他无关的事情:由于CA在某些情况下会引发异常以传达身份验证失败,因此从度量角度来看,这会增加Lambda ErrorCount度量。因此,该指标不可靠,无法识别“应用程序错误”。

  • @MauricioQuiroga 没有官方文档解释这一切。答案基于我的尝试和错误以及与 AWS 支持人员的一些讨论。 (2认同)