【问题标题】:API Gateway Custom Authorizer: Control error message and codeAPI Gateway Custom Authorizer:控制错误消息和代码
【发布时间】:2018-11-14 02:37:03
【问题描述】:

我的网关 API 有一个自定义授权方。我已经阅读了许多关于如何自定义在身份验证或授权错误时返回给最终用户的错误消息和代码的文章。 This one seemed the most useful.

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

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

def lambda_handler(event, context):
    raise Exception('the sky is falling!')

当我使用 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$ 

如何使它返回带有{"message": "the sky is falling!"} 的HTTP 4xx?


为了调试:我去了我的 API 下的网关响应,并从这里更新了“授权人配置错误 (500)”的“正文映射模板”:

{"message":$context.error.messageString}

到这里:

{
      "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"
 }

响应是:

 {
      "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"


 }

我读过:

AWS 论坛上还有更多内容。

【问题讨论】:

    标签: java amazon-web-services http authentication aws-api-gateway


    【解决方案1】:

    如果它对某人有帮助:

    CA = 自定义授权人

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

    其他不相关的事情:因为 CA 在某些情况下抛出异常以传达身份验证失败,所以从指标的角度来看,这会增加 Lambda ErrorCount 指标。因此,该指标不能可靠地识别“应用程序错误”。

    【讨论】:

    • @Kashyap 您能否为您的答案添加链接或文档参考?你的陈述基于什么?谢谢
    • @MauricioQuiroga 没有官方文档可以解释这一切。答案基于我的反复试验以及与 AWS 支持的一些讨论。
    • 这很有帮助。谢谢:)
    【解决方案2】:

    授权者和网关响应的映射是通过

    https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html

    您可以在此处更改返回状态码以自定义状态码。

    至于错误消息,我只是尝试在授权方输出的上下文中添加一个字段,如此处所述,https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html

    并在我的模板映射中为 access_denied 引用该字段为 $context.authorizer.myErrorMsg

    如果我的授权人输出拒绝策略文档,它就会起作用。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2020-03-17
      • 2019-12-25
      • 2011-07-10
      • 1970-01-01
      • 2020-07-11
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多