如何通过Terraform启用API Gateway端点授权以使用AWS Cognito用户池
问题分析
已成功将AWS Cognito作为授权器附加到API Gateway,但无法通过Terraform为端点启用授权配置(授权标志和OAuth范围)。当前代码存在两个核心问题:
- 安全规则(
security)被错误放置在CORS配置(x-amazon-apigateway-cors)中,而非全局或具体端点的操作定义内 - OpenAPI定义中的安全方案(
securitySchemes)与单独创建的Cognito授权器未正确关联
解决方案
1. 调整安全方案配置
在components/securitySchemes中补充x-amazon-apigateway-authorizer字段,关联Cognito用户池;同时修正类型定义(Cognito用户池授权需结合oauth2类型与cognito_user_pools认证类型)。
2. 为端点操作添加安全规则
在每个需要启用授权的端点操作(如/pets/get、/pets/post等)中添加security字段,指定要使用的授权器及所需的OAuth范围。
3. 移除冗余配置
删除CORS配置中错误放置的security节点,避免配置冲突。
修改后的完整代码
#Create API Gateway resource "aws_api_gateway_rest_api" "manidemoapi" { name = "manidemoapi" body = <<EOF { "openapi": "3.0.1", "info": { "title": "Example Pet Store", "description": "A Pet Store API.", "version": "1.0" }, # 可选:全局安全规则,对所有端点生效,个别端点例外可单独设置security为[] "security": [ { "manicognito-authorizer": ["get_details"] } ], "paths": { "/pets": { "get": { "operationId": "GET HTTP", # 单独为该端点配置安全规则(若全局已配置可省略) "security": [ { "manicognito-authorizer": ["get_details"] } ], "parameters": [ { "name": "type", "in": "query", "schema": { "type": "string" } }, { "name": "page", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "200 response", "headers": { "Access-Control-Allow-Origin": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Pets" } } } } }, "x-amazon-apigateway-integration": { "type": "HTTP_PROXY", "httpMethod": "GET", "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets", "payloadFormatVersion": 1.0 } }, "post": { "operationId": "Create Pet", "security": [ { "manicognito-authorizer": ["create_pet"] } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewPet" } } }, "required": true }, "responses": { "200": { "description": "200 response", "headers": { "Access-Control-Allow-Origin": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewPetResponse" } } } } }, "x-amazon-apigateway-integration": { "type": "HTTP_PROXY", "httpMethod": "POST", "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets", "payloadFormatVersion": 1.0 } } }, "/pets/{petId}": { "get": { "operationId": "Get Pet", "security": [ { "manicognito-authorizer": ["get_details"] } ], "parameters": [ { "name": "petId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "200 response", "headers": { "Access-Control-Allow-Origin": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Pet" } } } } }, "x-amazon-apigateway-integration": { "type": "HTTP_PROXY", "httpMethod": "GET", "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets/{petId}", "payloadFormatVersion": 1.0 } } } }, "x-amazon-apigateway-cors": { "allowOrigins": [ "*" ], "allowMethods": [ "GET", "OPTIONS", "POST" ], "allowHeaders": [ "x-amzm-header", "x-apigateway-header", "x-api-key", "authorization", "x-amz-date", "content-type" ] }, "components": { "securitySchemes": { "manicognito-authorizer": { "type": "oauth2", "flows": { "authorizationCode": { "authorizationUrl": "https://your-cognito-domain.auth.us-west-1.amazoncognito.com/oauth2/authorize", "tokenUrl": "https://your-cognito-domain.auth.us-west-1.amazoncognito.com/oauth2/token", "scopes": { "get_details": "获取宠物详情", "create_pet": "创建宠物" } } }, "x-amazon-apigateway-authtype": "cognito_user_pools", "x-amazon-apigateway-authorizer": { "type": "cognito_user_pools", "providerARNs": ["${aws_cognito_user_pool.pool.arn}"] } } }, "schemas": { "Pets": { "type": "array", "items": { "$ref": "#/components/schemas/Pet" } }, "Empty": { "type": "object" }, "NewPetResponse": { "type": "object", "properties": { "pet": { "$ref": "#/components/schemas/Pet" }, "message": { "type": "string" } } }, "Pet": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" } } }, "NewPet": { "type": "object", "properties": { "type": { "$ref": "#/components/schemas/PetType" }, "price": { "type": "number" } } }, "PetType": { "type": "string", "enum": [ "dog", "cat", "fish", "bird", "gecko" ] } } } } EOF endpoint_configuration { types = ["REGIONAL"] } } #Deploy API Gateway resource "aws_api_gateway_deployment" "manidemoapi" { rest_api_id = aws_api_gateway_rest_api.manidemoapi.id triggers = { redeployment = sha1(jsonencode(aws_api_gateway_rest_api.manidemoapi.body)) } lifecycle { create_before_destroy = true } } resource "aws_api_gateway_stage" "manidemoapi" { deployment_id = aws_api_gateway_deployment.manidemoapi.id rest_api_id = aws_api_gateway_rest_api.manidemoapi.id stage_name = "manidemoapi-dev" } # 可选择移除单独的授权器资源,因为已在OpenAPI定义中配置了授权器 # resource "aws_api_gateway_authorizer" "manidemoapi" { # name = "manicognito-authorizer" # type = "COGNITO_USER_POOLS" # rest_api_id = aws_api_gateway_rest_api.manidemoapi.id # provider_arns = [aws_cognito_user_pool.pool.arn] # }
关键修改说明
- 将
security规则从CORS配置移至全局或各个端点操作内,确保API Gateway识别到授权要求 - 修正
securitySchemes的类型为oauth2,并配置Cognito的授权/令牌端点及自定义范围 - 在
securitySchemes中通过x-amazon-apigateway-authorizer直接关联Cognito用户池ARN,无需单独创建aws_api_gateway_authorizer资源(若保留单独资源,需确保名称与OpenAPI中的授权器名称一致)
内容的提问来源于stack exchange,提问作者Ranopriyo Neogy
相关产品推荐
相关产品推荐

