AWS CDK user pool authorizer

This is my solution in TypeScript (based somewhat on bgdnlp's response)

import { App, Stack, Aws } from '@aws-cdk/core';
import { Code, Function, Runtime } from '@aws-cdk/aws-lambda';
import { LambdaIntegration, RestApi, CfnAuthorizer, CfnMethod } from '@aws-cdk/aws-apigateway';

const app = new App();
const stack = new Stack(app, `mystack`);
const api = new RestApi(stack, `myapi`);

const region = Aws.REGION;
const account = Aws.ACCOUNT_ID;
const cognitoArn = `arn:aws:cognito-idp:${region}:${account}:userpool/${USER_POOL_ID}`;

const authorizer = new CfnAuthorizer(stack, 'Authorizer', {
  name: `myauthorizer`,
  restApiId: api.restApiId,
  type: 'COGNITO_USER_POOLS',
  identitySource: 'method.request.header.Authorization',
  providerArns: [cognitoArn],
});

const lambda = new Function(stack, 'mylambda', {
  runtime: Runtime.NODEJS_10_X,
  code: Code.asset('dist'),
  handler: `index.handler`,
});

const integration = new LambdaIntegration(lambda);

const res = api.root.addResource('hello');

const method = res.addMethod('GET', integration);

const child = method.node.findChild('Resource') as CfnMethod;

child.addPropertyOverride('AuthorizationType', 'COGNITO_USER_POOLS');

child.addPropertyOverride('AuthorizerId', { Ref: authorizer.logicalId });

The previous answers no longer work because the authorizerId property was replaced with authorizer, which isn't fully implemented at this time.

Instead, it can be done by using the underlying CfnResource objects, as described in the official guide.

Here's Python code as an example:

from aws_cdk import cdk
from aws_cdk import aws_apigateway


class Stk(cdk.Stack):
    def __init__(self, app, id):
        super().__init__(app, id)

        api_gw = aws_apigateway.RestApi(self, 'MyApp')
        post_method = api_gw.root.add_method(http_method='POST')

        # Create authorizer using low level CfnResource
        api_gw_authorizer = aws_apigateway.CfnAuthorizer(
            scope=self,
            id='my_authorizer',
            rest_api_id=api_gw.rest_api_id,
            name='MyAuth',
            type='COGNITO_USER_POOLS',
            identity_source='method.request.header.name.Authorization',
            provider_arns=[
                'arn:aws:cognito-idp:eu-west-1:123456789012:userpool/'
                'eu-west-1_MyCognito'])

        # Get underlying post_method Resource object. Returns CfnMethod
        post_method_resource = post_method.node.find_child('Resource')
        # Add properties to low level resource
        post_method_resource.add_property_override('AuthorizationType',
                                                   'COGNITO_USER_POOLS')
        # AuthorizedId uses Ref, simulate with a dictionaty
        post_method_resource.add_property_override(
                'AuthorizerId',
                {"Ref": api_gw_authorizer.logical_id})


app = cdk.App()
stk = Stk(app, "myStack")

app.synth()

As of September 2019 @bgdnip answer doesnt translate exactly for typescript. I got it working with the following:

const api = new RestApi(this, 'RestAPI', {
    restApiName: 'Rest-Name',
    description: 'API for journey services.',
});

const putIntegration = new LambdaIntegration(handler);

const auth = new CfnAuthorizer(this, 'APIGatewayAuthorizer', {
    name: 'customer-authorizer',
    identitySource: 'method.request.header.Authorization',
    providerArns: [providerArn.valueAsString],
    restApiId: api.restApiId,
    type: AuthorizationType.COGNITO,
});

const post = api.root.addMethod('PUT', putIntegration, { authorizationType: AuthorizationType.COGNITO });
const postMethod = post.node.defaultChild as CfnMethod;
postMethod.addOverride('Properties.AuthorizerId', { Ref: auth.logicalId });

This is from https://docs.aws.amazon.com/cdk/latest/guide/cfn_layer.html#cfn_layer_resource_props

UPDATE October

The above is already out of date and unnecessary and can be achieved with the following with aws-cdk 1.12.0

const api = new RestApi(this, 'RestAPI', {
    restApiName: 'Rest-Name',
    description: 'API for journey services.',
});

const putIntegration = new LambdaIntegration(handler);

const auth = new CfnAuthorizer(this, 'APIGatewayAuthorizer', {
    name: 'customer-authorizer',
    identitySource: 'method.request.header.Authorization',
    providerArns: [providerArn.valueAsString],
    restApiId: api.restApiId,
    type: AuthorizationType.COGNITO,
});

const post = api.root.addMethod('PUT', putIntegration, {
    authorizationType: AuthorizationType.COGNITO,
    authorizer: { authorizerId: auth.ref }
});

Indeed. there is no example to do this via copy and paste ;). here is my example to create AWS cognito user pool and connect user pol authorizer with API gateway and lambda function using AWS CDK based on Java with Version 0.24.1.

This example ist just an example to provide an protected API for function called "Foo".

  • Cognito User Pool
  • API Gateway
  • Lambda
  • DynamoDB

    // -----------------------------------------------------------------------
    // Cognito User Pool
    // -----------------------------------------------------------------------
    CfnUserPool userPool = new CfnUserPool(this, "cognito",
        CfnUserPoolProps.builder()
            .withAdminCreateUserConfig(
                AdminCreateUserConfigProperty.builder()
                    .withAllowAdminCreateUserOnly(false)
                    .build())
            .withPolicies(
                PoliciesProperty.builder()
                    .withPasswordPolicy(
                        PasswordPolicyProperty.builder()
                            .withMinimumLength(6)
                            .withRequireLowercase(false)
                            .withRequireNumbers(false)
                            .withRequireSymbols(false)
                            .withRequireUppercase(false)
                            .build()
                    )
                    .build()
            )
            .withAutoVerifiedAttributes(Arrays.asList("email"))
            .withSchema(Arrays.asList(
                CfnUserPool.SchemaAttributeProperty.builder()
                    .withAttributeDataType("String")
                    .withName("email")
                    .withRequired(true)
                    .build()))
            .build());
    
    // -----------------------------------------------------------------------
    // Cognito User Pool Client
    // -----------------------------------------------------------------------
    new CfnUserPoolClient(this, "cognitoClient",
        CfnUserPoolClientProps.builder()
            .withClientName("UserPool")
            .withExplicitAuthFlows(Arrays.asList("ADMIN_NO_SRP_AUTH"))
            .withRefreshTokenValidity(90)
            .withUserPoolId(userPool.getRef())
            .build());
    
    // -----------------------------------------------------------------------
    // Lambda function
    // -----------------------------------------------------------------------
    Function function = new Function(this, "function.foo",
        FunctionProps.builder()
            // lamda code located in /functions/foo
            .withCode(Code.asset("functions/foo"))
            .withHandler("index.handler")
            .withRuntime(Runtime.NODE_J_S810)
            .build());
    
    // -----------------------------------------------------------------------
    // DynamoDB Table
    // -----------------------------------------------------------------------
    Table table = new Table(this, "dynamodb.foo", TableProps.builder()
        .withTableName("foo")
        .withPartitionKey(Attribute.builder()
            .withName("id")
            .withType(AttributeType.String)
            .build())
        .build());
    
    // GRANTS function -> table
    table.grantReadWriteData(function.getRole());
    
    // -----------------------------------------------------------------------
    // API Gateway
    // -----------------------------------------------------------------------
    
    // API Gateway REST API with lambda integration
    LambdaIntegration lambdaIntegration = new LambdaIntegration(function);
    RestApi restApi = new RestApi(this, "foo");
    
    // Authorizer configured with cognito user pool
    CfnAuthorizer authorizer = new CfnAuthorizer(this, "authorizer",
        CfnAuthorizerProps.builder()
            .withName("cognitoAuthorizer")
            .withRestApiId(restApi.getRestApiId())
            .withIdentitySource("method.request.header.Authorization")
            .withProviderArns(Arrays.asList(userPool.getUserPoolArn()))
            .withType("COGNITO_USER_POOLS")
            .build());
    
    // Bind authorizer to API ressource
    restApi.getRoot().addMethod("ANY", lambdaIntegration, MethodOptions
        .builder()
          .withAuthorizationType(AuthorizationType.Cognito)
          .withAuthorizerId(authorizer.getAuthorizerId())
        .build());