简体   繁体   English

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

[英]API Gateway Custom Authorizer: Control error message and code

I have a custom authorizer for my Gateway API. 我的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. 问题是API网关的行为与记录不符。

My custom authorizer implementation (python): 我的自定义授权器实现(python):

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

When I call the API using curl: 当我使用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$ 

How do I make it return HTTP 4xx with {"message": "the sky is falling!"} ? 如何让它返回带有{"message": "the sky is falling!"} HTTP 4xx {"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: 为了调试:我在我的API下进入了网关响应并更新了“主机映射模板”中的“授权器配置错误(500)”:

{"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. 还有一些在AWS论坛上。

In case it helps someone: 万一它可以帮助某人:

CA = custom authorizer CA =自定义授权程序

  • error code : AWS doesn't fully allow a CA implementation to dictate the error code sent back to caller. 错误代码 :AWS不完全允许CA实现指示发送回调用方的错误代码。
    • If the CA returns an Auth Policy which does not have resource/method that was invoked in one of the statements with action Allow , then user gets a 403 with something like "Not authorized to access resource" 如果CA返回的Auth策略没有在其中一个带有操作Allow的语句中调用的资源/方法,则用户将获得403,其中包含“未授权访问资源”的内容
    • If the CA returns an Auth Policy which has statements with action Deny that contains resource/method that was invoked, then user gets a 403 with something like "access denied explicitly with a Deny" 如果CA返回一个Auth策略,该策略具有包含已调用的资源/方法的操作Deny的语句,则用户将获得403,其中包含“使用拒绝显式拒绝访问”
    • If the Exception raised by CA has message "Unauthorized" then user gets 401 with message "Unauthorized". 如果CA引发的异常消息“未授权”,则用户获得401消息“未授权”。
    • If CA throws an exception with any other message then user gets HTTP-500 internal server error (Authorizer Configuration Error) and call is rejected/not-authorized. 如果CA引发任何其他消息的异常,则用户将获得HTTP-500内部服务器错误(授权者配置错误),并且拒绝/未授权呼叫。
  • error message : Only static control is allowed via Body Mapping Template in Gateway Responses. 错误消息 :仅允许通过网关响应中的正文映射模板进行静态控制。
    • Eg you can update the Body Mapping Template for "Unauthorized [401]" in "Gateway Responses" to say "My service doesn't like you for some unknown reason" and then whenever CA throws "Unauthorized" exception the end user gets HTTP 401 with "My service doesn't like you for some unknown reason". 例如,您可以在“网关响应”中更新“未授权[401]”的正文映射模板,说“我的服务因某种未知原因而不喜欢您”,然后每当CA抛出“未授权”异常时,最终用户都会获得HTTP 401与“我的服务因某种未知原因不喜欢你”。
    • Similarly you can also update "Access Denied [403]" or "Authorizer Configuration Error [500]". 同样,您也可以更新“拒绝访问[403]”或“授权程序配置错误[500]”。 But the message is static and can not be controlled from CA implementation. 但该消息是静态的,无法通过CA实现进行控制。
    • It is NOT possible to have different 401 messages like: 它是不可能有不同的401点的消息,如:
    • 401: Unauthorized due to expired token. 401:由于令牌过期而未经授权。
    • 401: Unauthorized due to missing scope. 401:由于缺少范围而未经授权。

Other unrelated thing: Because the CA throws an exception in certain conditions to convey auth failure, from a metric point of view this increments the Lambda ErrorCount metric. 其他无关的事情:因为CA在某些条件下抛出异常来传递auth失败,从度量的角度来看,这会增加Lambda ErrorCount度量。 So that metric isn't reliable to identify "application errors". 因此,该指标对于识别“应用程序错误”是不可靠的。

the mapping of authorizer and gateway response is done through 授权者和网关响应的映射是通过完成的

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

you can change the return status code there to customize the status code. 您可以在那里更改返回状态代码以自定义状态代码。

As to error message, i just tried adding a field to my context output by authorizer, as documented here, https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html 至于错误消息,我只是尝试通过授权器向我的上下文输出添加一个字段,如此处所述, https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output。 HTML

and referring to that field in my template mapping for access_denied as $context.authorizer.myErrorMsg 并在我的模板映射中引用access_denied为$ context.authorizer.myErrorMsg的字段

and it works if my authorizer outputs a deny policy document. 如果我的授权人输出拒绝政策文件,它就有效。

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS API Gateway 自定义授权方 lambda - AWS API Gateway Custom Authorizer lambda AWS API Gateway定制授权者。 如何在Lambda中访问principalId - AWS API Gateway custom authorizer. How to access principalId in lambda Spring 云网关 - 找不到路由时的自定义 404 错误消息 - Spring Cloud Gateway - custom 404 error message when route is not found Spring 验证 @AssertTrue 自定义错误代码/消息 - Spring validation @AssertTrue custom error code/message 自定义IDM身份验证和授权者 - Custom IDM authentication and Authorizer AngularJS显示403 HTTP错误代码的自定义错误消息/页面 - AngularJS show custom error message / page for 403 http error code 如何枚举错误代码和消息与自定义执行集成 - How to enum error code and message Integrate with Custom Execption 在Spring Boot中无法从REST API返回错误代码和消息 - Not able to return error code with message from rest API in Spring boot 为什么在通过 API 网关调用时,Java 中的 AWS Lambda 代码返回“内部服务器错误”? - why does this AWS Lambda code in Java return "internal server error" when invoked via an API gateway? 在Twitter API请求中获取错误代码消息(Java) - Getting the error code message in twitter api request (java)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM