Amazon web services AWS API网关与自定义授权人和CORS间歇性200然后403然后200。。。奇怪的

Amazon web services AWS API网关与自定义授权人和CORS间歇性200然后403然后200。。。奇怪的,amazon-web-services,cors,aws-api-gateway,amazon-cloudformation,Amazon Web Services,Cors,Aws Api Gateway,Amazon Cloudformation,我有一个1 Amazon Api网关设置和一个自定义授权器(授权器基本上只返回allow for anything) 我启用了CORS,这是从jQuery网页运行的 我有两种方法 /车辆(返回车辆列表) /预订(返回预订详细信息) 我看到的行为是,第一个请求进展顺利,我看到它拉取选项,然后执行获取请求然后,我点击另一个方法,选项起作用,然后get返回一个403,但是如果我再次启动请求(在同一资源上),我会得到一个200 我正在使用Cloudformation,但我在使用无服务器框架时注意到了相同

我有一个1 Amazon Api网关设置和一个自定义授权器(授权器基本上只返回allow for anything)

我启用了CORS,这是从jQuery网页运行的

我有两种方法

  • /车辆(返回车辆列表)
  • /预订(返回预订详细信息)
  • 我看到的行为是,第一个请求进展顺利,我看到它拉取选项,然后执行获取请求然后,我点击另一个方法,选项起作用,然后get返回一个403,但是如果我再次启动请求(在同一资源上),我会得到一个200

    我正在使用Cloudformation,但我在使用无服务器框架时注意到了相同的行为

    下面是我的一些屏幕截图,希望其他人也看到了这种奇怪

    下面是我的Cloudformation YAML模板的一部分,我正在一边学习

     HelloAPI:
        Type: AWS::Serverless::Api
        Properties:
          StageName: !Sub ${Environment}
          DefinitionBody:
            swagger: 2.0
            info:
              title:
                Ref: AWS::StackName
            securityDefinitions:
              test-authorizer:
                type: apiKey
                name: Authorization
                in: header
                x-amazon-apigateway-authtype: custom
                x-amazon-apigateway-authorizer:
                  type: token
                  authorizerUri:
                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerFunc.Arn}/invocations
                  authorizerResultTtlInSeconds: 5
            paths:
              /vehicles:
                get:
                  x-amazon-apigateway-integration:
                    httpMethod: POST
                    type: aws_proxy
                    uri:
                      !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${VehiclesLambda.Arn}/invocations
                  responses: {}
                  security:
                    - test-authorizer: []
                options:
                  tags:
                  - "CORS"
                  summary: "CORS support"
                  description: "Enable CORS by returning correct headers\n"
                  consumes:
                  - "application/json"
                  produces:
                  - "application/json"
                  parameters: []
                  responses:
                    "200":
                      description: "Default response for CORS method"
                      headers:
                        Access-Control-Allow-Headers:
                          type: "string"
                        Access-Control-Allow-Methods:
                          type: "string"
                        Access-Control-Allow-Origin:
                          type: "string"
                  x-amazon-apigateway-integration:
                    type: "mock"
                    requestTemplates:
                      application/json: "{\n  \"statusCode\" : 200\n}\n"
                    responses:
                      default:
                        statusCode: "200"
                        responseParameters:
                          method.response.header.Access-Control-Allow-Headers: "'X-Amz-Date,Authorization,X-Api-Key'"
                          method.response.header.Access-Control-Allow-Methods: "'*'"
                          method.response.header.Access-Control-Allow-Origin: "'*'"
                        responseTemplates:
                          application/json: "{}\n"
              /bookings:
                get:
                  x-amazon-apigateway-integration:
                    httpMethod: POST
                    type: aws_proxy
                    uri:
                      !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${BookingsLambda.Arn}/invocations
                  responses: {}
                  security:
                    - test-authorizer: []
                options:
                  tags:
                  - "CORS"
                  summary: "CORS support"
                  description: "Enable CORS by returning correct headers\n"
                  consumes:
                  - "application/json"
                  produces:
                  - "application/json"
                  parameters: []
                  responses:
                    "200":
                      description: "Default response for CORS method"
                      headers:
                        Access-Control-Allow-Headers:
                          type: "string"
                        Access-Control-Allow-Methods:
                          type: "string"
                        Access-Control-Allow-Origin:
                          type: "string"
                  x-amazon-apigateway-integration:
                    type: "mock"
                    requestTemplates:
                      application/json: "{\n  \"statusCode\" : 200\n}\n"
                    responses:
                      default:
                        statusCode: "200"
                        responseParameters:
                          method.response.header.Access-Control-Allow-Headers: "'X-Amz-Date,Authorization,X-Api-Key'"
                          method.response.header.Access-Control-Allow-Methods: "'*'"
                          method.response.header.Access-Control-Allow-Origin: "'*'"
                        responseTemplates:
                          application/json: "{}\n"
    
    这是我的任何事情都可以授权人

    'use strict';
    
    const generatePolicy = function(principalId, effect, resource) {
        const authResponse = {};
        authResponse.principalId = principalId;
        if (effect && resource) {
            const policyDocument = {};
            policyDocument.Version = '2012-10-17';
            policyDocument.Statement = [];
            const statementOne = {};
            statementOne.Action = 'execute-api:Invoke';
            statementOne.Effect = effect;
            statementOne.Resource = resource;
            policyDocument.Statement[0] = statementOne;
            authResponse.policyDocument = policyDocument;
        }
        return authResponse;
    };
    
    exports.handler = (event, context, callback) => {
    
        console.log("Hit Authorizer")
        console.log(event)
    
    
        callback(null, generatePolicy('user123', 'Allow', event.methodArn));
    
    }; 
    
    其他人看到了吗,或者知道如何调试它

    我把它放在一个测试网站上,只是有人想看看我看到了什么


    在自定义授权人代码中的第行

    statementOne.Resource = resource;
    
    将您的资源更改为以下格式:“arn:aws:executeapi:us-west-2:123456789012:ymy8tbxw7b/*/GET/”

    在您的情况下,允许:

    statementOne.Resource = arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/*/
    
    这就是AWS理解您的授权人的方式。因为在custom authorizer中,您可以从请求头(如用户、组等)获取信息,然后根据您的授权数据库验证信息,并决定允许谁或什么继续请求类型POST/get/选项,但API网关将不知道您的决定,直到您以AWS格式提供有效答案

    {
      "principalId": "yyyyyyyy", // The principal user identification associated with the token sent by the client.
      "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Action": "execute-api:Invoke",
            "Effect": "Allow|Deny",
            "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{appId}/{stage}/{httpVerb}/[{resource}/[child-resources]]"
          }
        ]
      },
      "context": {
        "stringKey": "value",
        "numberKey": "1",
        "booleanKey": "true"
      },
      "usageIdentifierKey": "{api-key}"  # Optional
    }
    
    您可以访问此页面了解更多信息:


    刚刚与AWS代表讨论了一个类似的问题。目前的问题是lambda authorizer缓存,它不同于API网关缓存

    默认情况下,您可能有lambda authorizer缓存(见图),因此,当您最初发出请求时,您的策略(特定于单个资源)会被缓存以用于TTL。对使用同一LAMBDA授权者的不同资源的后续请求将为原始资源返回相同的策略,而原始资源不是手头的资源,因此,您将得到403

    将返回的策略更改为更一般的策略a la@Dominic Nguyen的答案是一种解决方案(通常包括添加/*s),但您也可以执行我所做的操作,只需在lambda授权器上禁用缓存:


    然后,记得重新部署!!!Rep告诉我在那之后等待30秒,然后进行测试。

    你能发布授权人的内容吗?添加了授权人确保你的声明One.Resource=Resource的格式为“arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/”。在您的情况下,如果允许所有内容都是“arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/*/*/”Dung,我不确定您建议将其放在何处。。在YAML中的API定义中?或者在授权人中。在授权人中,在“statementOne.Resource=Resource;”行