I have a custom authorizer for my Gateway API. I've read many articles on how to customize the error message and code returned to end user when on authentication or authorization errors. This one seemed the most useful.
Problem is the API Gateway doesn't behave as documented.
My custom authorizer implementation (python):
def lambda_handler(event, context):
raise Exception('the sky is falling!')
When I call the API using curl:
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$
How do I make it return HTTP 4xx with {"message": "the sky is falling!"}
?
For debugging: I went to Gateway Responses under my API and updated the "Body Mapping Templates" for "Authorizer Configuration Error (500)" from this:
{"message":$context.error.messageString}
to this:
{
"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"
}
and the response is:
{
"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"
}
I've read:
and some more on AWS forums.
答案 0 :(得分:5)
以防万一:
CA =自定义授权者
其他无关的事情:由于CA在某些情况下会引发异常以传达身份验证失败,因此从度量角度来看,这会增加Lambda ErrorCount度量。因此,该指标不可靠,无法识别“应用程序错误”。
答案 1 :(得分:0)
授权者和网关响应的映射是通过
完成的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
,并且如果我的授权者输出拒绝政策文件,此方法就起作用。
希望有帮助