部署后 AWS API 网关 api 密钥未设置为 'true'

AWS API Gateway api key required not set to 'true' after deployment

我有一个 .NET 解决方案,它使用 SAM 模板生成 cloudformation 来部署堆栈。我期待部署 - 一旦完成 - 在至少一种方法上具有 API Key Required = true。但是在部署之后,创建了密钥和使用计划,但是在控制台中所需的 api 密钥仍然设置为 false?

见下文:

我的 SAM 模板:

    "ServerlessRestApi": {
        "Type": "AWS::ApiGateway::RestApi",
        "Properties": {
            "Description":"This is a placeholder for the description of this web api",
            "Body": {
                "info": {
                    "version": "1.0",
                    "title": {
                        "Ref": "AWS::StackName"
                    }
                },
                "x-amazon-apigateway-api-key-source": "HEADER",
                "paths": {
                    "datagw/general/table/get/{tableid}": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        },
                        "security":[
                                    {
                                        "api_key":[]
                                    }
                                ]},
                                "securityDefinitions":{
                                    "api_key":{
                                        "type":"apiKey",
                                        "name":"x-api-key",
                                        "in":"header"
                                }
                    },
                    "/": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    },
                    "/tables/{tableid}/{columnid}": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    }
                },
                "swagger": "2.0"
            }
        }
    },

我对 swagger 的定义不是很熟悉,我只知道 SAM 和 CloudFormation 的基础知识。我在这里错过了什么?我已经查看了有关堆栈溢出的其他答案,并相信我已经正确复制了配置。

当我检查生成的 CloudFormation 时,我关于 x-api-key 的条目甚至没有出现在模板中?

  "ServerlessRestApi": {
        "Type": "AWS::ApiGateway::RestApi",
        "Properties": {
            "Body": {
                "info": {
                    "version": "1.0",
                    "title": {
                        "Ref": "AWS::StackName"
                    }
                },
                "paths": {
                    "datagw/general/table/get/{tableid}": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    },
                    "/datagw/general/webhook/ccnotify": {
                        "post": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectNotification.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    },
                    "/": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    },
                    "/tables/{tableid}/{columnid}": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    },
                    "/datagw/general/post/sohupdate": {
                        "post": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "POST",
                                "type": "aws_proxy",
                                "uri": {
                                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectStockUpdate.Arn}/invocations"
                                }
                            },
                            "responses": {}
                        }
                    }
                },
                "swagger": "2.0"
            }
        }
    },

编辑:这就是我所做的,但是一旦部署完成,API 所需的密钥在 API 中仍未设置为 true。

"ServerlessRestApi": {
    "Type": "AWS::ApiGateway::RestApi",
    "Properties": {
        "Description":"InSite Web API Version 2.0.0.0",
        "Body": {
            "swagger": "2.0",
            "info": {
                "version": "1.0",
                "title": {
                    "Ref": "AWS::StackName"
                }
            },
            "x-amazon-apigateway-api-key-source" : "HEADER",
            "schemes":["https"],
            "paths": {
                "tables/query/{tableid}": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "GET",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
                            }
                        },
                        "responses": {},
                            "security": [
                            {
                                "api_key": []
                            }
                        ]
                    }
                },
                "/products/update/": {
                    "post": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "POST",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectStockUpdate.Arn}/invocations"
                            }
                        },
                        "responses": {}
                    }
                },
                "/": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "GET",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
                            }
                        },
                        "responses": {}
                    }
                },
                "/tables/{tableid}/{columnid}": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "GET",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
                            }
                        },
                        "responses": {}
                    }
                }
            },
            "securityDefinitions": {
                "api_key": {
                    "type": "apiKey",
                    "name": "x-api-key",
                    "in": "header"
                }
            }
        }
    }
},

我认为你错过了 "securityDefinitions":

  Body:
    swagger: "2.0"
      ...
      ...
    securityDefinitions:
      sigv4:
        type: "apiKey"
        name: "x-api-key"
        in: "header"
        x-amazon-apigateway-authorizer:
          type: token

您可以在此处找到更多示例: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-as-s3-proxy-export-swagger-with-extensions.html

所以首先,如果您使用的是 SAM 框架,那么为什么不尝试具有 Auth 的无服务器 API (AWS::Serverless::Api) 对象,您可以在其中打开 ApiKeyRequired.

https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi

"ServerlessRestApi": {
    "Type": "AWS::Serverless::Api",
    "Properties": {
        "Description":"InSite Web API Version 2.0.0.0",
        "Auth": {
            "ApiKeyRequired": "true"
        },
        "DefinitionBody": {
            "swagger": "2.0",
            "info": {
                "version": "1.0",
                "title": {
                    "Ref": "AWS::StackName"
                }
            },
            "x-amazon-apigateway-api-key-source" : "HEADER",
            "schemes":["https"],
            "paths": {
                "tables/query/{tableid}": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "GET",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
                            }
                        },
                        "responses": {},
                            "security": [
                            {
                                "api_key": []
                            }
                        ]
                    }
                },
                "/products/update/": {
                    "post": {
                     "x-amazon-apigateway-integration": {
                            "httpMethod": "POST",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectStockUpdate.Arn}/invocations"
                            }
                        },
                        "responses": {}
                    }
                },
                "/": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "GET",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
                            }
                        },
                        "responses": {}
                    }
                },
                "/tables/{tableid}/{columnid}": {
                    "get": {
                        "x-amazon-apigateway-integration": {
                            "httpMethod": "GET",
                            "type": "aws_proxy",
                            "uri": {
                                "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
                            }
                        },
                        "responses": {}
                    }
                }
            },
            "securityDefinitions": {
                "api_key": {
                    "type": "apiKey",
                    "name": "x-api-key",
                    "in": "header"
                }
            }
        }
    }
},

如果由于某种原因您无法使用无服务器,您可能会尝试使 RestApi 过载(这很好,但您会失去一些其他细粒度选项)。为了全面披露,我不以这种方式使用 API 网关(我使用无服务器转换),所以这都是阅读文档而不是经验。

我会尝试创建一个简单的骨架 AWS::ApiGateway::RestApi,然后通过 RestApiId.[=13= 引用它,将 AWS::ApiGateway::Method 附加到 RestApi ]

[1] https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-method.html