首页 > 解决方案 > AWS CDK - API Gateway 上的 Cognito UserPool 授权方不起作用

问题描述

我的目标是设置一些公开的 lambda 函数(即发送请求不需要授权)和其他需要用户在 Cognito UserPool 中登录的函数。

在下面的 CDK 文件中,我仅在两个端点之一上添加了授权者,但是当我启动请求时,它们都不受保护,并且在函数日志中您可以看到没有 Cognito UserPool 或 AuthenticationType。

关于缺少什么的任何想法?

谢谢!

{
   "httpMethod":"GET",
   "body":null,
   "resource":"/private",
   "requestContext":{
      ...,
      "identity":{
         "apiKey":null,
         "userArn":null,
         "cognitoAuthenticationType":null,
         "caller":null,
         "userAgent":"Custom User Agent String",
         "user":null,
         "cognitoIdentityPoolId":null,
         "cognitoAuthenticationProvider":null,
         "sourceIp":"127.0.0.1",
         "accountId":null
      },
      ...
   },
   ...
}

CDK 文件:

import * as apigateway from '@aws-cdk/aws-apigateway';
import * as lambda from '@aws-cdk/aws-lambda';
import * as s3 from '@aws-cdk/aws-s3';
import { UserPool, VerificationEmailStyle, UserPoolClient } from '@aws-cdk/aws-cognito'
import { App, CfnParameter, Duration, Stack, StackProps } from '@aws-cdk/core';


export class CdkStack extends Stack {
    constructor(scope: App, id: string, props: StackProps) {
        super(scope, id, props);

        new CfnParameter(this, 'AppId');

        const userPool = new UserPool(this, 'dev-users', {
            userPoolName: 'dev-users',
            selfSignUpEnabled: true,
            userVerification: {
                emailSubject: 'Verify your email for our awesome app!',
                emailBody: 'Hello {username}, Thanks for signing up to our awesome app! Your verification code is {####}',
                emailStyle: VerificationEmailStyle.CODE,
                smsMessage: 'Hello {username}, Thanks for signing up to our awesome app! Your verification code is {####}',
            },
            signInAliases: {
                email: true
            },
            signInCaseSensitive: false,
            standardAttributes: {
                email: { required: true, mutable: false }
            },
            passwordPolicy: {
                minLength: 6,
                requireLowercase: true,
                requireUppercase: true,
                requireDigits: true,
                requireSymbols: false,
                tempPasswordValidity: Duration.days(7),
            }
        })

        const environment = {  };
        // The code will be uploaded to this location during the pipeline's build step
        const artifactBucket = s3.Bucket.fromBucketName(this, 'ArtifactBucket', process.env.S3_BUCKET!);
        const artifactKey = `${process.env.CODEBUILD_BUILD_ID}/function-code.zip`;
        const code = lambda.Code.fromBucket(artifactBucket, artifactKey);

        // This is a Lambda function config associated with the source code: get-all-items.js
        const publicFunction = new lambda.Function(this, 'publicFunction', {
            description: 'A simple example includes a HTTP get method accessible to everyone',
            handler: 'src/handlers/public.publicHandler',
            runtime: lambda.Runtime.NODEJS_10_X,
            code,
            environment,
            timeout: Duration.seconds(60),
        });
        // Give Read permissions to the SampleTable


        // This is a Lambda function config associated with the source code: put-item.js
        const privateFunction = new lambda.Function(this, 'privateFunction', {
            description: 'This functions should only be accessible to authorized users from a Cognito UserPool',
            handler: 'src/handlers/private.privateHandler',
            runtime: lambda.Runtime.NODEJS_10_X,
            code,
            timeout: Duration.seconds(60),
            environment,
        });

        const api = new apigateway.RestApi(this, 'ServerlessRestApi', { cloudWatchRole: false });

        const authorizer = new apigateway.CfnAuthorizer(this, 'cfnAuth', {
            restApiId: api.restApiId,
            name: 'HelloWorldAPIAuthorizer',
            type: 'COGNITO_USER_POOLS',
            identitySource: 'method.request.header.Authorization',
            providerArns: [userPool.userPoolArn],
        })

        api.root.addResource('public').addMethod(
            'GET',
            new apigateway.LambdaIntegration(publicFunction)
        );
        api.root.addResource('private').addMethod(
            'GET',
            new apigateway.LambdaIntegration(privateFunction),
            {
                authorizationType: apigateway.AuthorizationType.COGNITO,
                authorizer: {
                    authorizerId: authorizer.ref
                }
            }
        );
    }
}

const app = new App();
new CdkStack(app, 'CognitoProtectedApi', {});
app.synth();

标签: amazon-web-servicesaws-lambdaaws-api-gatewayamazon-cognitoaws-cdk

解决方案


推荐阅读