aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

[aws-apigateway] impossible to remove default method authorization

Open erik-sab opened this issue 5 years ago • 19 comments

It seems not possible to remove authorization for API Gateway methods if it is defined in defaultMethodOptions on RestApi level.

Reproduction Steps

First I create RestApi Gateway (https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.RestApi.html) with custom authorizer set by default for all methods:

        var apiGw = RestApi.Builder.create(scope, "Stack-RestApi")
                .defaultMethodOptions(MethodOptions.builder()
                        .apiKeyRequired(Boolean.FALSE)
                        .authorizationType(AuthorizationType.CUSTOM)
                        .authorizer(authorizer)
                        .build())
...

And then in resources stack I try to create documentation Method (https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.Method.html) with security disabled:

        Method.Builder builder = Method.Builder.create(scope, "Stack-ApiInfoMethodGET")
                .options(MethodOptions.builder()
                        .apiKeyRequired(Boolean.FALSE)
                        .authorizationType(AuthorizationType.NONE)
                        .authorizer(null) // tried to reset authorizer also
                        .build())
...

Error Log

[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project cdk-stacks: An exception occured while executing the Java class. Stack-ApiGwResource/Stack-ApiInfoResource/GET - Authorization type is set to NONE which is different from what is required by the authorizer [CUSTOM]
[ERROR] Error: Stack-ApiGwResource/Stack-ApiInfoResource/GET - Authorization type is set to NONE which is different from what is required by the authorizer [CUSTOM]
[ERROR]     at new Method (/tmp/jsii-kernel-TH8eSk/node_modules/@aws-cdk/aws-apigateway/lib/method.js:27:19)
[ERROR]     at /tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:7906:49
[ERROR]     at Kernel._wrapSandboxCode (/tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:8382:19)
[ERROR]     at Kernel._create (/tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:7906:26)
[ERROR]     at Kernel.create (/tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:7650:21)
[ERROR]     at KernelHost.processRequest (/tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:7439:28)
[ERROR]     at KernelHost.run (/tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:7377:14)
[ERROR]     at Immediate._onImmediate (/tmp/jsii-java-runtime16647868641746308035/jsii-runtime.js:7380:37)
[ERROR]     at processImmediate (internal/timers.js:456:21)

Environment

  • CLI Version : 1.47.0
  • Framework Version: 1.47.0
  • Node.js Version: v12.18.1
  • OS : Ubuntu Linux
  • Language (Version): Java 11

Other

It is still possible to override these setting as described in https://github.com/aws/aws-cdk/issues/8615

        var cfnMethod = (CfnMethod) method.getNode().getDefaultChild();
        cfnMethod.addPropertyOverride("ApiKeyRequired", false);
        cfnMethod.addPropertyOverride("AuthorizationType", "NONE");
        cfnMethod.addPropertyDeletionOverride("AuthorizerId");

and then stack is created with correct Method-level security settings.


This is :bug: Bug Report

erik-sab avatar Jul 01 '20 04:07 erik-sab

It does seem like we don't handle the NONE case correctly here - https://github.com/aws/aws-cdk/blob/31d6e6596cde03daa7de48aab8aaae1277fd405e/packages/%40aws-cdk/aws-apigateway/lib/method.ts#L182-L186

nija-at avatar Jul 13 '20 14:07 nija-at

I’ve also noticed a similar issue trying to set apiKeyRequired: false when I’ve got apiKeyRequired: true in defaultMethodOptions: https://github.com/aws/aws-cdk/blob/31d6e6596cde03daa7de48aab8aaae1277fd405e/packages/%40aws-cdk/aws-apigateway/lib/method.ts#L203 I think || should be ??

mattsenior avatar Sep 29 '20 10:09 mattsenior

https://github.com/aws/aws-cdk/blob/31d6e6596cde03daa7de48aab8aaae1277fd405e/packages/%40aws-cdk/aws-apigateway/lib/method.ts#L203

I think || should be ??

IMHO it is not so simple, as we need to distinguish when options.apiKeyRequired is not set.

Probably should be something like:

apiKeyRequired = (options.apiKeyRequired !== undefined && options.apiKeyRequired !== null) ?
    options.apiKeyRequired :
    defaultMethodOptions.apiKeyRequired

Only not sure what is current default for options.apiKeyRequired

erik-sab avatar Oct 02 '20 07:10 erik-sab

@erik-telesoftas Hey I’m not sure I follow, that’s what ?? does, right?

mattsenior avatar Oct 03 '20 21:10 mattsenior

@mattsenior absolutely right, probably fool moon on top of my JS syntax ignorance ;)

erik-sab avatar Oct 05 '20 05:10 erik-sab

Of possibly related trouble is the inability to instruct a particular method not to use an authorizer, once defaultMethodOptions is set @nija-at

shellscape avatar Mar 25 '21 21:03 shellscape

Hi @nija-at, will there be any progress on this issue soon? As a workaround one could write an aspect that removes the authorizer from certain methods. Not beautiful, but would work.

const excludedMethodIds: Method[] = [];

const aspect: IAspect = {
  visit(node: IConstruct): void {
    if (
      node instanceof CfnMethod
      && !excludedMethodIds.find((rid) => rid === node.resourceId)
    ) {
      delete node.authorizerId;
      node.authorizationType = AuthorizationType.NONE;
    }
  },
};

Aspects.of(myStack).add(aspect);

bmacher avatar Nov 09 '21 11:11 bmacher

https://github.com/aws/aws-cdk/blob/31d6e6596cde03daa7de48aab8aaae1277fd405e/packages/%40aws-cdk/aws-apigateway/lib/method.ts#L203

This issue (the || needing to be ??) is what is causing https://github.com/aws/aws-cdk/issues/8615 to still be broken if the default is to have API key required since the fix added in https://github.com/aws/aws-cdk/pull/22402 seems to get overridden by the default setting - options.apiKeyRequired is false which leads the other side of the boolean operator to get evaluated which then returns whatever defaultMethodOptions.apiKeyRequired is set to.

markcarroll avatar Nov 23 '22 17:11 markcarroll

facing the same issue as well with IAM:

Authorization type is set to AWS_IAM which is different from what is required by the authorizer [COGNITO_USER_POOLS]

this is the part of code that does the check: https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-apigateway/lib/method.ts#L187-L198

and this is the test that covers it: https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-apigateway/test/method.test.ts#L700-L716

I'm trying to understand the reason of enforcing all route to use the "default authorizer" while API Gateway does allow to have a route that uses Cognito and another one that uses IAM (eg. for internal services for example).

I think the only check that makes sense to do is the one covered by this other test: https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-apigateway/test/method.test.ts#L685-L698

mirgj avatar Nov 25 '22 09:11 mirgj

Hello from 2023, I have the same problem :)

stleon avatar Mar 19 '23 22:03 stleon

@rix0rrr given this one is coming up on 3 years old it could probably use some eyeballs if just for confirmation.

shellscape avatar Mar 19 '23 23:03 shellscape

same

devpascoe avatar Mar 20 '23 00:03 devpascoe

@mattsenior @markcarroll submitted a PR for the apiKeyRequired here https://github.com/aws/aws-cdk/pull/25682.

?? works - made a unit test for it as well - https://github.com/aws/aws-cdk/pull/25682/files#diff-2a75ad420d0c98981d7269b81d6496388ba7399a933e05b43d6d13686b181833R1334

iRoachie avatar May 23 '23 13:05 iRoachie

Hi @nija-at, will there be any progress on this issue soon? As a workaround one could write an aspect that removes the authorizer from certain methods. Not beautiful, but would work.

const excludedMethodIds: Method[] = [];

const aspect: IAspect = {
  visit(node: IConstruct): void {
    if (
      node instanceof CfnMethod
      && !excludedMethodIds.find((rid) => rid === node.resourceId)
    ) {
      delete node.authorizerId;
      node.authorizationType = AuthorizationType.NONE;
    }
  },
};

Aspects.of(myStack).add(aspect);

This didn't work for me.

In the end, I had to set my API root's default authorization type to NONE and then set the authorizer at the top of every tree in my API that consists entirely of endpoints requiring authorization. So overriding a default of NONE with an authorizer works, but overriding a default authorizer with NONE does not. Not ideal.

@nija-at: is there any plan to fix this?

cupid-dev avatar Jun 21 '23 22:06 cupid-dev

Hi @cupid-dev - I no longer work for the AWS CDK. Someone from the team will respond to you in due time.

nija-at avatar Jun 22 '23 07:06 nija-at

This issue has received a significant amount of attention so we are automatically upgrading its priority. A member of the community will see the re-prioritization and provide an update on the issue.

github-actions[bot] avatar Jul 30 '23 00:07 github-actions[bot]

Any updates on this issue? Authorization type is set to NONE which is different from what is required by the authorizer [CUSTOM]

charlierharper avatar Jan 17 '24 15:01 charlierharper

As a workaround, you can use the CDK -> CloudFormation escape hatch.

In Python, that looks like this: noauth_method.node.default_child.add_property_override("AuthorizationType", "NONE")

More details at https://github.com/aws/aws-cdk/issues/29658

kcp-chewie avatar Apr 02 '24 03:04 kcp-chewie

+1

HansFalkenberg-Visma avatar Apr 23 '24 22:04 HansFalkenberg-Visma

#29658

Doing this removes the authorizer for every route though. AWS CDK is the worst, very little documentation, very little support. This issue has been activer since July 2020????

typefox09 avatar May 30 '24 05:05 typefox09

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

github-actions[bot] avatar Jun 01 '24 07:06 github-actions[bot]