From 1b8d73cb33ca62dd035ca339d3f1b5acc251338c Mon Sep 17 00:00:00 2001 From: Mohamed Elasmar <71043312+moelasmar@users.noreply.github.com> Date: Sat, 1 Jun 2024 00:59:27 -0700 Subject: [PATCH] fix(apigateway): allow overriding authorizer on methods (#30415) ### Issue # (if applicable) Closes #8827. ### Reason for this change Customers could not override the authorizer defined in the default method configuration if they want to set the authorization type to None. ### Description of changes If the customer set the authorization type to None while creating a new method, we will not use the authorizer value defined in the default configuration and instead we will set it to undefined. ### Description of how you validated changes added unit, and integration test cases. ### Checklist - [X] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssert5491B2D1.assets.json | 19 + ...aultTestDeployAssert5491B2D1.template.json | 36 ++ .../cdk.out | 1 + .../integ.json | 12 + ...-overriding-default-authorizer.assets.json | 19 + ...verriding-default-authorizer.template.json | 272 +++++++++++ .../manifest.json | 173 +++++++ .../tree.json | 461 ++++++++++++++++++ ....api-with-overriding-default-authorizer.ts | 70 +++ .../aws-cdk-lib/aws-apigateway/lib/method.ts | 5 +- .../aws-apigateway/test/method.test.ts | 60 ++- 11 files changed, 1125 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets.json new file mode 100644 index 0000000000000..972130241b34e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integ.json new file mode 100644 index 0000000000000..e74f6e90acf13 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "apigateway-with-overriding-default-authorizer/DefaultTest": { + "stacks": [ + "integtest-restapi-with-overriding-default-authorizer" + ], + "assertionStack": "apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert", + "assertionStackName": "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.assets.json new file mode 100644 index 0000000000000..fcf8829b9a9af --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "d1b9f5b2f5a16dd3d551be97ea2814cf6d8f574c561523bdf07541d86d27934c": { + "source": { + "path": "integtest-restapi-with-overriding-default-authorizer.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d1b9f5b2f5a16dd3d551be97ea2814cf6d8f574c561523bdf07541d86d27934c.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.template.json new file mode 100644 index 0000000000000..66236eb4e1b03 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/integtest-restapi-with-overriding-default-authorizer.template.json @@ -0,0 +1,272 @@ +{ + "Resources": { + "UserPool6BA7E5F2": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AccountRecoverySetting": { + "RecoveryMechanisms": [ + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } + ] + }, + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": false + }, + "AutoVerifiedAttributes": [ + "email" + ], + "EmailVerificationMessage": "The verification code to your new account is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsVerificationMessage": "The verification code to your new account is {####}", + "UsernameAttributes": [ + "email" + ], + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "The verification code to your new account is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "AuthorizerBD825682": { + "Type": "AWS::ApiGateway::Authorizer", + "Properties": { + "IdentitySource": "method.request.header.Authorization", + "Name": "integtestrestapiwithoverridingdefaultauthorizerAuthorizerF0743170", + "ProviderARNs": [ + { + "Fn::GetAtt": [ + "UserPool6BA7E5F2", + "Arn" + ] + } + ], + "RestApiId": { + "Ref": "ActionsApiGatewayF80386B7" + }, + "Type": "COGNITO_USER_POOLS" + } + }, + "ActionsApiGatewayF80386B7": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Name": "Actions-ApiGateway" + } + }, + "ActionsApiGatewayDeployment50B6E6A66403e42852ae63ad13a2b7635300f8a9": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "Description": "Automatically created by the RestApi construct", + "RestApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + }, + "DependsOn": [ + "ActionsApiGatewayANY11FE5E47", + "ActionsApiGatewayGET12E87C75", + "ActionsApiGatewayOPTIONS8EA1F997", + "AuthorizerBD825682" + ] + }, + "ActionsApiGatewayDeploymentStageprod812022BF": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ActionsApiGatewayDeployment50B6E6A66403e42852ae63ad13a2b7635300f8a9" + }, + "RestApiId": { + "Ref": "ActionsApiGatewayF80386B7" + }, + "StageName": "prod" + } + }, + "ActionsApiGatewayOPTIONS8EA1F997": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "ApiKeyRequired": false, + "AuthorizationType": "NONE", + "HttpMethod": "OPTIONS", + "Integration": { + "IntegrationResponses": [ + { + "ResponseParameters": { + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", + "method.response.header.Access-Control-Allow-Origin": "'*'", + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD'", + "method.response.header.Access-Control-Max-Age": "'864000'" + }, + "StatusCode": "204" + } + ], + "RequestTemplates": { + "application/json": "{ statusCode: 200 }" + }, + "Type": "MOCK" + }, + "MethodResponses": [ + { + "ResponseParameters": { + "method.response.header.Access-Control-Allow-Headers": true, + "method.response.header.Access-Control-Allow-Origin": true, + "method.response.header.Access-Control-Allow-Methods": true, + "method.response.header.Access-Control-Max-Age": true + }, + "StatusCode": "204" + } + ], + "ResourceId": { + "Fn::GetAtt": [ + "ActionsApiGatewayF80386B7", + "RootResourceId" + ] + }, + "RestApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + }, + "ActionsApiGatewayANY11FE5E47": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "AuthorizationType": "NONE", + "HttpMethod": "ANY", + "Integration": { + "IntegrationResponses": [ + { + "StatusCode": "200" + } + ], + "PassthroughBehavior": "NEVER", + "RequestTemplates": { + "application/json": "{ \"statusCode\": 200 }" + }, + "Type": "MOCK" + }, + "MethodResponses": [ + { + "StatusCode": "200" + } + ], + "ResourceId": { + "Fn::GetAtt": [ + "ActionsApiGatewayF80386B7", + "RootResourceId" + ] + }, + "RestApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + }, + "ActionsApiGatewayGET12E87C75": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "AuthorizationScopes": [ + "scope" + ], + "AuthorizationType": "COGNITO_USER_POOLS", + "AuthorizerId": { + "Ref": "AuthorizerBD825682" + }, + "HttpMethod": "GET", + "Integration": { + "IntegrationResponses": [ + { + "StatusCode": "200" + } + ], + "PassthroughBehavior": "NEVER", + "RequestTemplates": { + "application/json": "{ \"statusCode\": 200 }" + }, + "Type": "MOCK" + }, + "MethodResponses": [ + { + "StatusCode": "200" + } + ], + "ResourceId": { + "Fn::GetAtt": [ + "ActionsApiGatewayF80386B7", + "RootResourceId" + ] + }, + "RestApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + } + }, + "Outputs": { + "ActionsApiGatewayEndpoint261B645B": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "ActionsApiGatewayF80386B7" + }, + ".execute-api.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "ActionsApiGatewayDeploymentStageprod812022BF" + }, + "/" + ] + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/manifest.json new file mode 100644 index 0000000000000..8df93a4b207a8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/manifest.json @@ -0,0 +1,173 @@ +{ + "version": "36.0.0", + "artifacts": { + "integtest-restapi-with-overriding-default-authorizer.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integtest-restapi-with-overriding-default-authorizer.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integtest-restapi-with-overriding-default-authorizer": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integtest-restapi-with-overriding-default-authorizer.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d1b9f5b2f5a16dd3d551be97ea2814cf6d8f574c561523bdf07541d86d27934c.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integtest-restapi-with-overriding-default-authorizer.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integtest-restapi-with-overriding-default-authorizer.assets" + ], + "metadata": { + "/integtest-restapi-with-overriding-default-authorizer/UserPool/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "UserPool6BA7E5F2" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Authorizer/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AuthorizerBD825682" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayF80386B7" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Deployment/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayDeployment50B6E6A66403e42852ae63ad13a2b7635300f8a9" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/DeploymentStage.prod/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayDeploymentStageprod812022BF" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Endpoint": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayEndpoint261B645B" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/OPTIONS": [ + { + "type": "aws:cdk:warning", + "data": "'AuthorizationScopes' can only be set when 'AuthorizationType' sets 'COGNITO_USER_POOLS'. Default to ignore the values set in 'AuthorizationScopes'. [ack: @aws-cdk/aws-apigateway:invalidAuthScope]" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/OPTIONS/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayOPTIONS8EA1F997" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/ANY": [ + { + "type": "aws:cdk:warning", + "data": "'AuthorizationScopes' can only be set when 'AuthorizationType' sets 'COGNITO_USER_POOLS'. Default to ignore the values set in 'AuthorizationScopes'. [ack: @aws-cdk/aws-apigateway:invalidAuthScope]" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/ANY/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayANY11FE5E47" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/GET/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ActionsApiGatewayGET12E87C75" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integtest-restapi-with-overriding-default-authorizer/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integtest-restapi-with-overriding-default-authorizer" + }, + "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "apigatewaywithoverridingdefaultauthorizerDefaultTestDeployAssert5491B2D1.assets" + ], + "metadata": { + "/apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/tree.json new file mode 100644 index 0000000000000..00019e1e09667 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.js.snapshot/tree.json @@ -0,0 +1,461 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integtest-restapi-with-overriding-default-authorizer": { + "id": "integtest-restapi-with-overriding-default-authorizer", + "path": "integtest-restapi-with-overriding-default-authorizer", + "children": { + "UserPool": { + "id": "UserPool", + "path": "integtest-restapi-with-overriding-default-authorizer/UserPool", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/UserPool/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool", + "aws:cdk:cloudformation:props": { + "accountRecoverySetting": { + "recoveryMechanisms": [ + { + "name": "verified_phone_number", + "priority": 1 + }, + { + "name": "verified_email", + "priority": 2 + } + ] + }, + "adminCreateUserConfig": { + "allowAdminCreateUserOnly": false + }, + "autoVerifiedAttributes": [ + "email" + ], + "emailVerificationMessage": "The verification code to your new account is {####}", + "emailVerificationSubject": "Verify your new account", + "smsVerificationMessage": "The verification code to your new account is {####}", + "usernameAttributes": [ + "email" + ], + "verificationMessageTemplate": { + "defaultEmailOption": "CONFIRM_WITH_CODE", + "emailMessage": "The verification code to your new account is {####}", + "emailSubject": "Verify your new account", + "smsMessage": "The verification code to your new account is {####}" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" + } + }, + "Authorizer": { + "id": "Authorizer", + "path": "integtest-restapi-with-overriding-default-authorizer/Authorizer", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Authorizer/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Authorizer", + "aws:cdk:cloudformation:props": { + "identitySource": "method.request.header.Authorization", + "name": "integtestrestapiwithoverridingdefaultauthorizerAuthorizerF0743170", + "providerArns": [ + { + "Fn::GetAtt": [ + "UserPool6BA7E5F2", + "Arn" + ] + } + ], + "restApiId": { + "Ref": "ActionsApiGatewayF80386B7" + }, + "type": "COGNITO_USER_POOLS" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnAuthorizer", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CognitoUserPoolsAuthorizer", + "version": "0.0.0" + } + }, + "Actions-ApiGateway": { + "id": "Actions-ApiGateway", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::RestApi", + "aws:cdk:cloudformation:props": { + "name": "Actions-ApiGateway" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnRestApi", + "version": "0.0.0" + } + }, + "Deployment": { + "id": "Deployment", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Deployment", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Deployment/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Deployment", + "aws:cdk:cloudformation:props": { + "description": "Automatically created by the RestApi construct", + "restApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnDeployment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Deployment", + "version": "0.0.0" + } + }, + "DeploymentStage.prod": { + "id": "DeploymentStage.prod", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/DeploymentStage.prod", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/DeploymentStage.prod/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Stage", + "aws:cdk:cloudformation:props": { + "deploymentId": { + "Ref": "ActionsApiGatewayDeployment50B6E6A66403e42852ae63ad13a2b7635300f8a9" + }, + "restApiId": { + "Ref": "ActionsApiGatewayF80386B7" + }, + "stageName": "prod" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnStage", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Stage", + "version": "0.0.0" + } + }, + "Endpoint": { + "id": "Endpoint", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Endpoint", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default", + "children": { + "OPTIONS": { + "id": "OPTIONS", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/OPTIONS", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/OPTIONS/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", + "aws:cdk:cloudformation:props": { + "apiKeyRequired": false, + "authorizationType": "NONE", + "httpMethod": "OPTIONS", + "integration": { + "type": "MOCK", + "requestTemplates": { + "application/json": "{ statusCode: 200 }" + }, + "integrationResponses": [ + { + "statusCode": "204", + "responseParameters": { + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", + "method.response.header.Access-Control-Allow-Origin": "'*'", + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD'", + "method.response.header.Access-Control-Max-Age": "'864000'" + } + } + ] + }, + "methodResponses": [ + { + "statusCode": "204", + "responseParameters": { + "method.response.header.Access-Control-Allow-Headers": true, + "method.response.header.Access-Control-Allow-Origin": true, + "method.response.header.Access-Control-Allow-Methods": true, + "method.response.header.Access-Control-Max-Age": true + } + } + ], + "resourceId": { + "Fn::GetAtt": [ + "ActionsApiGatewayF80386B7", + "RootResourceId" + ] + }, + "restApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnMethod", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Method", + "version": "0.0.0" + } + }, + "ANY": { + "id": "ANY", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/ANY", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/ANY/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", + "aws:cdk:cloudformation:props": { + "authorizationType": "NONE", + "httpMethod": "ANY", + "integration": { + "type": "MOCK", + "requestTemplates": { + "application/json": "{ \"statusCode\": 200 }" + }, + "passthroughBehavior": "NEVER", + "integrationResponses": [ + { + "statusCode": "200" + } + ] + }, + "methodResponses": [ + { + "statusCode": "200" + } + ], + "resourceId": { + "Fn::GetAtt": [ + "ActionsApiGatewayF80386B7", + "RootResourceId" + ] + }, + "restApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnMethod", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Method", + "version": "0.0.0" + } + }, + "GET": { + "id": "GET", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/GET", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-restapi-with-overriding-default-authorizer/Actions-ApiGateway/Default/GET/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", + "aws:cdk:cloudformation:props": { + "authorizationScopes": [ + "scope" + ], + "authorizationType": "COGNITO_USER_POOLS", + "authorizerId": { + "Ref": "AuthorizerBD825682" + }, + "httpMethod": "GET", + "integration": { + "type": "MOCK", + "requestTemplates": { + "application/json": "{ \"statusCode\": 200 }" + }, + "passthroughBehavior": "NEVER", + "integrationResponses": [ + { + "statusCode": "200" + } + ] + }, + "methodResponses": [ + { + "statusCode": "200" + } + ], + "resourceId": { + "Fn::GetAtt": [ + "ActionsApiGatewayF80386B7", + "RootResourceId" + ] + }, + "restApiId": { + "Ref": "ActionsApiGatewayF80386B7" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnMethod", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Method", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.ResourceBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.RestApi", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integtest-restapi-with-overriding-default-authorizer/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integtest-restapi-with-overriding-default-authorizer/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "apigateway-with-overriding-default-authorizer": { + "id": "apigateway-with-overriding-default-authorizer", + "path": "apigateway-with-overriding-default-authorizer", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "apigateway-with-overriding-default-authorizer/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "apigateway-with-overriding-default-authorizer/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "apigateway-with-overriding-default-authorizer/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.ts new file mode 100644 index 0000000000000..794c3fb1bbc14 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/authorizers/integ.api-with-overriding-default-authorizer.ts @@ -0,0 +1,70 @@ +import * as cdk from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as cognito from 'aws-cdk-lib/aws-cognito'; +import * as agw from 'aws-cdk-lib/aws-apigateway'; +import { AuthorizationType, MockIntegration, PassthroughBehavior } from 'aws-cdk-lib/aws-apigateway'; + +/* + * Stack verification steps: + * * `curl -i ` should return HTTP code 200 + */ + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'integtest-restapi-with-overriding-default-authorizer'); + +// create a cognito user pool +const userPool = new cognito.UserPool(stack, 'UserPool', { + selfSignUpEnabled: true, + signInAliases: { + email: true, + }, +}); + +const authorizer = new agw.CognitoUserPoolsAuthorizer(stack, 'Authorizer', { + cognitoUserPools: [userPool], +}); + +const api = new agw.RestApi(stack, 'Actions-ApiGateway', { + defaultCorsPreflightOptions: { + allowOrigins: agw.Cors.ALL_ORIGINS, + maxAge: cdk.Duration.days(10), + }, + defaultMethodOptions: { + authorizer: authorizer, + authorizationType: agw.AuthorizationType.COGNITO, + authorizationScopes: ['scope'], + }, +}); + +api.root.addMethod('ANY', new MockIntegration({ + integrationResponses: [ + { statusCode: '200' }, + ], + passthroughBehavior: PassthroughBehavior.NEVER, + requestTemplates: { + 'application/json': '{ "statusCode": 200 }', + }, +}), { + methodResponses: [ + { statusCode: '200' }, + ], + authorizationType: AuthorizationType.NONE, +}); + +api.root.addMethod('GET', new MockIntegration({ + integrationResponses: [ + { statusCode: '200' }, + ], + passthroughBehavior: PassthroughBehavior.NEVER, + requestTemplates: { + 'application/json': '{ "statusCode": 200 }', + }, +}), { + methodResponses: [ + { statusCode: '200' }, + ], +}); + +new IntegTest(app, 'apigateway-with-overriding-default-authorizer', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-apigateway/lib/method.ts b/packages/aws-cdk-lib/aws-apigateway/lib/method.ts index 98cf76c06d4a2..841e1b70bc511 100644 --- a/packages/aws-cdk-lib/aws-apigateway/lib/method.ts +++ b/packages/aws-cdk-lib/aws-apigateway/lib/method.ts @@ -187,7 +187,10 @@ export class Method extends Resource { const options = props.options || {}; const defaultMethodOptions = props.resource.defaultMethodOptions || {}; - const authorizer = options.authorizer || defaultMethodOptions.authorizer; + // do not use the default authorizer config in case if the provided authorizer type is None + const authorizer = + options.authorizationType === AuthorizationType.NONE + && options.authorizer == undefined ? undefined : options.authorizer || defaultMethodOptions.authorizer; const authorizerId = authorizer?.authorizerId ? authorizer.authorizerId : undefined; const authorizationTypeOption = options.authorizationType || defaultMethodOptions.authorizationType; diff --git a/packages/aws-cdk-lib/aws-apigateway/test/method.test.ts b/packages/aws-cdk-lib/aws-apigateway/test/method.test.ts index ad599dd86f19d..7cb2d63f59b08 100644 --- a/packages/aws-cdk-lib/aws-apigateway/test/method.test.ts +++ b/packages/aws-cdk-lib/aws-apigateway/test/method.test.ts @@ -4,6 +4,7 @@ import * as iam from '../../aws-iam'; import * as lambda from '../../aws-lambda'; import * as cdk from '../../core'; import * as apigw from '../lib'; +import { AuthorizationType } from '../lib'; const DUMMY_AUTHORIZER: apigw.IAuthorizer = { authorizerId: 'dummyauthorizer', @@ -697,9 +698,9 @@ describe('method', () => { expect(() => { restApi.root.addMethod('ANY', undefined, { - authorizationType: apigw.AuthorizationType.NONE, + authorizationType: apigw.AuthorizationType.IAM, }); - }).toThrow(/Authorization type is set to NONE which is different from what is required by the authorizer/); + }).toThrow(/Authorization type is set to AWS_IAM which is different from what is required by the authorizer/); }); @@ -756,6 +757,61 @@ describe('method', () => { }); + test('Override Authorization Type config in the default method config to None', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigw.RestApi(stack, 'test-api', { + cloudWatchRole: false, + deploy: false, + defaultMethodOptions: { + authorizationType: apigw.AuthorizationType.COGNITO, + authorizer: DUMMY_AUTHORIZER, + authorizationScopes: ['DefaultAuth'], + }, + }); + + // WHEN + new apigw.Method(stack, 'OverrideDefaultAuthScopes', { + httpMethod: 'POST', + resource: api.root, + options: { + operationName: 'overrideDefaultAuthScopes', + authorizationType: AuthorizationType.NONE, + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + OperationName: 'overrideDefaultAuthScopes', + AuthorizationType: AuthorizationType.NONE, + }); + + expect(Template.fromStack(stack).findResources('AWS::ApiGateway::Method', { + OperationName: 'overrideDefaultAuthScopes', + authorizer: DUMMY_AUTHORIZER, + })).toEqual({}); + + }); + + test('Add Method that override the default method config authorization type to None do not fail', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigw.RestApi(stack, 'test-api', { + cloudWatchRole: false, + deploy: false, + defaultMethodOptions: { + authorizationType: apigw.AuthorizationType.COGNITO, + authorizer: DUMMY_AUTHORIZER, + authorizationScopes: ['DefaultAuth'], + }, + }); + expect(() => { + api.root.addMethod('ANY', undefined, { + authorizationType: apigw.AuthorizationType.NONE, + }); + }).not.toThrow(/Authorization type is set to AWS_IAM which is different from what is required by the authorizer/); + }); + test.each([ [apigw.AuthorizationType.IAM, undefined], [apigw.AuthorizationType.NONE, undefined],