question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[apigateway] Unable to add COGNITO_USER_POOLS auth to API Gateway method

See original GitHub issue

Unable to add Cognito auth to API Gateway method

Reproduction Steps

        rescue_centre_api = aws_apigateway.RestApi(self, 'rescueCentreAPI', rest_api_name='rescueCentreAPI',
                                                   default_cors_preflight_options={
                                                       "allow_origins": ["*"],
                                                       "allow_methods": ["GET", "POST", "OPTIONS"]
                                                   })

        auth = aws_apigateway.CfnAuthorizer(self, "adminSectionAuth", rest_api_id=rescue_centre_api.rest_api_id,
                                            type='COGNITO_USER_POOLS', identity_source='method.request.header.Authorization',
                                            provider_arns=[
                                                'VALID_PREEXISTING_ARN'],
                                            name="adminSectionAuth"
                                            )
        rehomers_resource = rescue_centre_api.root.add_resource('rehomers')
       get_rehomers_lambda_function = aws_lambda.Function(self, "getrehomersLambda",
                                                           handler='app.lambda_handler',
                                                           runtime=aws_lambda.Runtime.PYTHON_3_8,
                                                           code=aws_lambda.Code.from_asset(
                                                               "lambdas/getLambda"),)
        get_rehomers_lambda_integration = aws_apigateway.LambdaIntegration(
            get_rehomers_lambda_function, proxy=True)
        rehomers_resource.add_method('GET', rehomers_lambda_integration,
                                     authorization_type=AuthorizationType.COGNITO,
                                     authorization_scopes=["openid", "profile", "email"], authorizer=auth)

Error Log

Invalid authorizer ID specified. Setting the authorization type to CUSTOM or COGNITO_USER_POOLS requires a valid authorizer. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 549f5e36-dadb-4c19-a14e-fa355b959793) new Method (C:\Users\User2\AppData\Local\Temp\jsii-kernel-vZCqgM\node_modules@aws-cdk\aws-apigateway\lib\method.js:46:26) _ Resource.addMethod (C:\Users\User2\AppData\Local\Temp\jsii-kernel-vZCqgM\node_modules@aws-cdk\aws-apigateway\lib\resource.js:17:16) _ C:\Users\User2\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:7739:51 _ Kernel._wrapSandboxCode (C:\Users\User2\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:8388:20) _ C:\Users\User2\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:7739:25 _ Kernel._ensureSync (C:\Users\User2\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:8364:20) _ Kernel.invoke (C:\Users\User2\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:7738:26) he\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:7377:14) _ Immediate._onImmediate (C:\Users\User2\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\jsii_embedded\jsii\jsii-runtime.js:7380:37) _ processImmediate (internal/timers.js:456:21)

Environment

  • **CLI Version 😗*1.51.0 (build 8c2d53c)
  • **Framework Version:**aws-cdk.aws-apigateway==1.45.0
  • Node.js Version: v12.16.3
  • **OS 😗*Windows 10
  • Language (Version): Python (3.8.3)

Other

The relevant section of the template as output by cdk synth doesn’t seem to include a ID at all. I added a AuthorizerId key to the template manually and deployed it to CloudFormation that way without issue.

rescueCentreAPIrehomersGETAE24A896:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: GET
      ResourceId:
        Ref: rescueCentreAPIrehomers3DD82C26
      RestApiId:
        Ref: rescueCentreAPID8DB9A2C
      AuthorizationScopes:
        - openid
        - profile
        - email
      AuthorizationType: COGNITO_USER_POOLS
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri:
          Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - ":apigateway:"
              - Ref: AWS::Region
              - :lambda:path/2015-03-31/functions/
              - Fn::GetAtt:
                  - rehomerApplicationLambdaBB2EE525
                  - Arn
              - /invocations
    Metadata:
      aws:cdk:path: backend/rescueCentreAPI/Default/rehomers/GET/Resource

This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
rrrixcommented, Jul 14, 2020

Here’s a TypeScript version of a Cognito User Pool Authorizer I built, modeled off of the CDK’s existing IAuthorizer implementations… maybe you can convert it to Python?

import { AuthorizationType, Authorizer, CfnAuthorizer, IAuthorizer, IRestApi } from '@aws-cdk/aws-apigateway';
import { Construct, Lazy, ResourceProps, Stack } from '@aws-cdk/core';

export interface CognitoAuthorizerProps extends ResourceProps {
  /**
   * (Optional) The name of this Authorizer
   *
   * @default The node's logical ID
   */
  authorizerName?: string;
  /**
   * The Identity Source (e.g. header, query string, etc.)
   *
   * @default `method.request.header.Authorization`
   */
  identitySource?: string;
  /**
   * The Cognito User Pool ARN
   */
  userPoolArn: string;
}

/**
 * Amazon Cognito IDP Authorizer for API Gateway REST APIs
 * @extends Authorizer
 * @implements IAuthorizer
 */
export class CognitoAuthorizer extends Authorizer implements IAuthorizer {
  /**
   * The Authorizer ID
   */
  public readonly authorizerId: string;
  /**
   * The API Gateway REST API ID this Authorizer is attached to
   */
  protected restApiId?: string;
  /**
   * The ARN of this Authorizer
   */
  public readonly authorizerArn: string;
  constructor(scope: Construct, id: string, props: CognitoAuthorizerProps) {
    super(scope, id, props);

    const restApiId = this.lazyRestApiId();
    const resource = new CfnAuthorizer(this, 'Resource', {
      name: props.authorizerName ?? this.node.uniqueId,
      restApiId,
      type: 'COGNITO_USER_POOLS',
      identitySource: props.identitySource || 'method.request.header.Authorization',
      providerArns: [props.userPoolArn],
    });

    this.authorizerId = resource.ref;
    this.authorizerArn = Stack.of(this).formatArn({
      service: 'cognito-idp',
      resource: restApiId,
      resourceName: `authorizers/${this.authorizerId}`,
    });
    // We have to do this because CDK's API Gateway L2 requires that IAuthorizers be "custom"
    // even though we have to make this COGNITO
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    this.authorizationType = AuthorizationType.COGNITO;
  }

  /**
   * Attaches this authorizer to a specific REST API.
   * @internal
   */
  public _attachToApi(restApi: IRestApi): void {
    if (this.restApiId && this.restApiId !== restApi.restApiId) {
      throw new Error('Cannot attach authorizer to two different rest APIs');
    }

    this.restApiId = restApi.restApiId;
  }
  /**
   * Returns a token that resolves to the Rest Api Id at the time of synthesis.
   * Throws an error, during token resolution, if no RestApi is attached to this authorizer.
   */
  protected lazyRestApiId(): string {
    return Lazy.stringValue({
      produce: () => {
        if (!this.restApiId) {
          throw new Error(`Authorizer (${this.node.path}) must be attached to a RestApi`);
        }
        return this.restApiId;
      },
    });
  }
}
0reactions
0xdevaliascommented, Jul 31, 2020

@rrrix would be awesome if you were able to open a PR to add your workaround in https://github.com/aws/aws-cdk/issues/9023#issuecomment-658309644 to CDK properly!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Set up Amazon Cognito user pools as an API Gateway ...
1. In the API Gateway console, choose the Test button under the new authorizer. · 2. In the Test window, for Authorization, enter...
Read more >
Secure your API Gateway with Amazon Cognito User Pools
Amazon Cognito is a powerful AWS service that enables user logins and federated identities. Cognito can be leveraged as an authentication ...
Read more >
How to Secure AWS API Gateway With Cognito User Pool
Navigate to the API Gateway service and click the Create API button. You will create a REST API thus click the Build button....
Read more >
Integrate a REST API with an Amazon Cognito user pool
After creating an Amazon Cognito user pool, in API Gateway, you must then create a COGNITO_USER_POOLS authorizer that uses the user pool.
Read more >
Cognito user pool does not show up API Gateway after setting ...
And yes, you are indeed right. You are facing the problem of the Authorizer not functioning because the Authorizer is not linked to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found