Skip to content

Commit

Permalink
Merge branch 'master' of github.com:aws/aws-cdk into chaimber/lambda_…
Browse files Browse the repository at this point in the history
…perm_cond
  • Loading branch information
BenChaimberg committed May 18, 2021
2 parents ea53bcc + 8856482 commit af2be84
Show file tree
Hide file tree
Showing 42 changed files with 1,369 additions and 32 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [1.104.0](https://github.com/aws/aws-cdk/compare/v1.103.0...v1.104.0) (2021-05-14)


### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES

* **apigatewayv2:** setting the authorizer of an API route to HttpNoneAuthorizer will now remove any existing authorizer on the route

### Features

* **appsync:** elasticsearch data source for graphql api ([#14651](https://github.com/aws/aws-cdk/issues/14651)) ([2337b5d](https://github.com/aws/aws-cdk/commit/2337b5d965028ba06d6ff72f991c0b8e46433a8f)), closes [#6063](https://github.com/aws/aws-cdk/issues/6063)
* **cfnspec:** cloudformation spec v35.2.0 ([#14610](https://github.com/aws/aws-cdk/issues/14610)) ([799ce1a](https://github.com/aws/aws-cdk/commit/799ce1a7d5fb261cae92d514b4f7e315d8f0e589))
* **cloudwatch:** GraphWidget supports period and statistic ([#14679](https://github.com/aws/aws-cdk/issues/14679)) ([b240f6e](https://github.com/aws/aws-cdk/commit/b240f6ece74d129e5f43b210e8ad12f95c4a2971))
* **cloudwatch:** time range support for GraphWidget ([#14659](https://github.com/aws/aws-cdk/issues/14659)) ([010a6b1](https://github.com/aws/aws-cdk/commit/010a6b1a14f14be5001779644df3d3a2e27d4e71)), closes [#4649](https://github.com/aws/aws-cdk/issues/4649)
* **ecs:** add support for EC2 Capacity Providers ([#14386](https://github.com/aws/aws-cdk/issues/14386)) ([114f7cc](https://github.com/aws/aws-cdk/commit/114f7ccdaf736988834fe2be487363a992a31369))
* **secretsmanager:** Automatically grant permissions to rotation Lambda ([#14471](https://github.com/aws/aws-cdk/issues/14471)) ([85e00fa](https://github.com/aws/aws-cdk/commit/85e00faf1e3bcc32c2f7aa881d42c6d1f6c17f63))


### Bug Fixes

* **apigatewayv2:** authorizer is not removed when HttpNoneAuthorizer is used ([#14424](https://github.com/aws/aws-cdk/issues/14424)) ([3698a91](https://github.com/aws/aws-cdk/commit/3698a91ac81a31f763c55487f200458d5b5eaf0f))
* **ecs:** Classes FargateService and Ec2Service have no defaultChild ([#14691](https://github.com/aws/aws-cdk/issues/14691)) ([348e11e](https://github.com/aws/aws-cdk/commit/348e11e26edc0ff90b623b7cec778f4935e61e6d)), closes [#14665](https://github.com/aws/aws-cdk/issues/14665)
* **events-targets:** circular dependency when adding a KMS-encrypted SQS queue ([#14638](https://github.com/aws/aws-cdk/issues/14638)) ([3063818](https://github.com/aws/aws-cdk/commit/3063818aa7c3c3ff56cf55254b0f6561db190a3e)), closes [#11158](https://github.com/aws/aws-cdk/issues/11158)
* **lambda:** custom resource fails to connect to efs filesystem ([#14431](https://github.com/aws/aws-cdk/issues/14431)) ([10a633c](https://github.com/aws/aws-cdk/commit/10a633c8cda9f21b85c82f911d88641f3a362c4d))
* **lambda-event-sources:** incorrect documented defaults for stream types ([#14562](https://github.com/aws/aws-cdk/issues/14562)) ([0ea24e9](https://github.com/aws/aws-cdk/commit/0ea24e95939412765c0e09133a7793557f779c76)), closes [#13908](https://github.com/aws/aws-cdk/issues/13908)
* **lambda-nodejs:** handler filename missing from error message ([#14564](https://github.com/aws/aws-cdk/issues/14564)) ([256fd4c](https://github.com/aws/aws-cdk/commit/256fd4c6fcdbe6519bc70f62415557dbeae950a1))

## [1.103.0](https://github.com/aws/aws-cdk/compare/v1.102.0...v1.103.0) (2021-05-10)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See: [Contributing Guide](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-ecs/README.md)
30 changes: 30 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- [Route Authorization](#route-authorization)
- [JWT Authorizers](#jwt-authorizers)
- [User Pool Authorizer](#user-pool-authorizer)
- [Lambda Authorizers](#lambda-authorizers)

## Introduction

Expand Down Expand Up @@ -162,3 +163,32 @@ api.addRoutes({
authorizer,
});
```

## Lambda Authorizers

Lambda authorizers use a Lambda function to control access to your HTTP API. When a client calls your API, API Gateway invokes your Lambda function and uses the response to determine whether the client can access your API.

Lambda authorizers depending on their response, fall into either two types - Simple or IAM. You can learn about differences [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html#http-api-lambda-authorizer.payload-format-response).


```ts
// This function handles your auth logic
const authHandler = new Function(this, 'auth-function', {
//...
});

const authorizer = new HttpLambdaAuthorizer({
responseTypes: [HttpLambdaAuthorizerType.SIMPLE] // Define if returns simple and/or iam response
handler: authHandler,
});

const api = new HttpApi(stack, 'HttpApi');

api.addRoutes({
integration: new HttpProxyIntegration({
url: 'https://get-books-proxy.myproxy.internal',
}),
path: '/books',
authorizer,
});
```
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './user-pool';
export * from './jwt';
export * from './jwt';
export * from './lambda';
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class HttpJwtAuthorizer implements IHttpRouteAuthorizer {

return {
authorizerId: this.authorizer.authorizerId,
authorizationType: HttpAuthorizerType.JWT,
authorizationType: 'JWT',
};
}
}
130 changes: 130 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/lambda.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import {
HttpAuthorizer,
HttpAuthorizerType,
HttpRouteAuthorizerBindOptions,
HttpRouteAuthorizerConfig,
IHttpRouteAuthorizer,
AuthorizerPayloadVersion,
IHttpApi,
} from '@aws-cdk/aws-apigatewayv2';
import { ServicePrincipal } from '@aws-cdk/aws-iam';
import { IFunction } from '@aws-cdk/aws-lambda';
import { Stack, Duration, Names } from '@aws-cdk/core';

// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports, import/order
import { Construct as CoreConstruct } from '@aws-cdk/core';

/**
* Specifies the type responses the lambda returns
*/
export enum HttpLambdaResponseType {
/** Returns simple boolean response */
SIMPLE,

/** Returns an IAM Policy */
IAM,
}

/**
* Properties to initialize HttpTokenAuthorizer.
*/
export interface HttpLambdaAuthorizerProps {

/**
* The name of the authorizer
*/
readonly authorizerName: string;

/**
* The identity source for which authorization is requested.
*
* @default ['$request.header.Authorization']
*/
readonly identitySource?: string[];

/**
* The lambda function used for authorization
*/
readonly handler: IFunction;

/**
* How long APIGateway should cache the results. Max 1 hour.
* Disable caching by setting this to `Duration.seconds(0)`.
*
* @default Duration.minutes(5)
*/
readonly resultsCacheTtl?: Duration;

/**
* The types of responses the lambda can return
*
* If HttpLambdaResponseType.SIMPLE is included then
* response format 2.0 will be used.
*
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html#http-api-lambda-authorizer.payload-format-response
*
* @default [HttpLambdaResponseType.IAM]
*/
readonly responseTypes?: HttpLambdaResponseType[];
}

/**
* Authorize Http Api routes via a lambda function
*/
export class HttpLambdaAuthorizer implements IHttpRouteAuthorizer {
private authorizer?: HttpAuthorizer;
private httpApi?: IHttpApi;

constructor(private readonly props: HttpLambdaAuthorizerProps) {
}

public bind(options: HttpRouteAuthorizerBindOptions): HttpRouteAuthorizerConfig {
if (this.httpApi && (this.httpApi.apiId !== options.route.httpApi.apiId)) {
throw new Error('Cannot attach the same authorizer to multiple Apis');
}

if (!this.authorizer) {
const id = this.props.authorizerName;

const responseTypes = this.props.responseTypes ?? [HttpLambdaResponseType.IAM];
const enableSimpleResponses = responseTypes.includes(HttpLambdaResponseType.SIMPLE) || undefined;

this.httpApi = options.route.httpApi;
this.authorizer = new HttpAuthorizer(options.scope, id, {
httpApi: options.route.httpApi,
identitySource: this.props.identitySource ?? [
'$request.header.Authorization',
],
type: HttpAuthorizerType.LAMBDA,
authorizerName: this.props.authorizerName,
enableSimpleResponses,
payloadFormatVersion: enableSimpleResponses ? AuthorizerPayloadVersion.VERSION_2_0 : AuthorizerPayloadVersion.VERSION_1_0,
authorizerUri: lambdaAuthorizerArn(this.props.handler),
resultsCacheTtl: this.props.resultsCacheTtl ?? Duration.minutes(5),
});

this.props.handler.addPermission(`${Names.nodeUniqueId(this.authorizer.node)}-Permission`, {
scope: options.scope as CoreConstruct,
principal: new ServicePrincipal('apigateway.amazonaws.com'),
sourceArn: Stack.of(options.route).formatArn({
service: 'execute-api',
resource: options.route.httpApi.apiId,
resourceName: `authorizers/${this.authorizer.authorizerId}`,
}),
});
}

return {
authorizerId: this.authorizer.authorizerId,
authorizationType: 'CUSTOM',
};
}
}

/**
* constructs the authorizerURIArn.
*/
function lambdaAuthorizerArn(handler: IFunction) {
return `arn:${Stack.of(handler).partition}:apigateway:${Stack.of(handler).region}:lambda:path/2015-03-31/functions/${handler.functionArn}/invocations`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class HttpUserPoolAuthorizer implements IHttpRouteAuthorizer {

return {
authorizerId: this.authorizer.authorizerId,
authorizationType: HttpAuthorizerType.JWT,
authorizationType: 'JWT',
};
}
}
4 changes: 4 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,16 @@
"dependencies": {
"@aws-cdk/aws-apigatewayv2": "0.0.0",
"@aws-cdk/aws-cognito": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/core": "0.0.0",
"constructs": "^3.3.69"
},
"peerDependencies": {
"@aws-cdk/aws-apigatewayv2": "0.0.0",
"@aws-cdk/aws-cognito": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/core": "0.0.0",
"constructs": "^3.3.69"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* eslint-disable no-console */

export const handler = async (event: AWSLambda.APIGatewayProxyEventV2) => {
const key = event.headers['x-api-key'];

return {
isAuthorized: key === '123',
};
};
Loading

0 comments on commit af2be84

Please sign in to comment.