Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apigateway): lambda request authorizer #5642

Merged
merged 11 commits into from
Feb 24, 2020
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pack/
.tools/
coverage/
.nyc_output
.nycrc
.LAST_BUILD
*.sw[a-z]
*~
Expand Down
48 changes: 44 additions & 4 deletions packages/@aws-cdk/aws-apigateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ API Gateway interacts with the authorizer Lambda function handler by passing inp
The event object that the handler is called with contains the `authorizationToken` and the `methodArn` from the request to the
API Gateway endpoint. The handler is expected to return the `principalId` (i.e. the client identifier) and a `policyDocument` stating
what the client is authorizer to perform.
See https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html for a detailed specification on
inputs and outputs of the lambda handler.
See [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) for a detailed specification on
inputs and outputs of the Lambda handler.

The following code attaches a token-based Lambda authorizer to the 'GET' Method of the Book resource:

Expand All @@ -382,7 +382,7 @@ const authFn = new lambda.Function(this, 'booksAuthorizerLambda', {
});

const auth = new apigateway.TokenAuthorizer(this, 'booksAuthorizer', {
function: authFn
handler: authFn
});

books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
Expand All @@ -397,6 +397,45 @@ Authorizers can also be passed via the `defaultMethodOptions` property within th
explicitly overridden, the specified defaults will be applied across all `Method`s across the `RestApi` or across all `Resource`s,
depending on where the defaults were specified.

#### Lambda-based request authorizer

This module provides support for request-based Lambda authorizers. When a client makes a request to an API's methods configured with such
an authorizer, API Gateway calls the Lambda authorizer, which takes specified parts of the request, known as identity sources,
as input and returns an IAM policy as output. A request-based Lambda authorizer (also called a request authorizer) receives
the identity sources in a series of values pulled from the request, from the headers, stage variables, query strings, and the context.

API Gateway interacts with the authorizer Lambda function handler by passing input and expecting the output in a specific format.
The event object that the handler is called with contains the body of the request and the `methodArn` from the request to the
API Gateway endpoint. The handler is expected to return the `principalId` (i.e. the client identifier) and a `policyDocument` stating
what the client is authorizer to perform.
See [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) for a detailed specification on
inputs and outputs of the Lambda handler.

The following code attaches a request-based Lambda authorizer to the 'GET' Method of the Book resource:

```ts
const authFn = new lambda.Function(this, 'booksAuthorizerLambda', {
// ...
// ...
});

const auth = new apigateway.RequestAuthorizer(this, 'booksAuthorizer', {
handler: authFn,
identitySources: [IdentitySource.header('Authorization')]
});

books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), {
authorizer: auth
});
```

By default, the `RequestAuthorizer` does not pass any kind of information from the request. This can,
however, be modified by changing the `identitySource` property, and is required when specifying a value for caching.

Authorizers can also be passed via the `defaultMethodOptions` property within the `RestApi` construct or the `Method` construct. Unless
explicitly overridden, the specified defaults will be applied across all `Method`s across the `RestApi` or across all `Resource`s,
depending on where the defaults were specified.

### Deployments

By default, the `RestApi` construct will automatically create an API Gateway
Expand Down Expand Up @@ -539,7 +578,8 @@ running at one origin, access to selected resources from a different origin. A
web application executes a cross-origin HTTP request when it requests a resource
that has a different origin (domain, protocol, or port) from its own.

You can add the CORS [preflight](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests) OPTIONS HTTP method to any API resource via the `defaultCorsPreflightOptions` option or by calling the `addCorsPreflight` on a specific resource.
You can add the CORS [preflight](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests) OPTIONS
HTTP method to any API resource via the `defaultCorsPreflightOptions` option or by calling the `addCorsPreflight` on a specific resource.

The following example will enable CORS for all methods and all origins on all resources of the API:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Represents an identity source.
*
* The source can be specified either as a literal value (e.g: `Auth`) which
* cannot be blank, or as an unresolved string token.
*/
export class IdentitySource {
CaerusKaru marked this conversation as resolved.
Show resolved Hide resolved
/**
* Provides a properly formatted header identity source.
* @param headerName the name of the header the `IdentitySource` will represent.
*
* @returns a header identity source.
*/
public static header(headerName: string): string {
return IdentitySource.toString(headerName, 'method.request.header');
}

/**
* Provides a properly formatted query string identity source.
* @param queryString the name of the query string the `IdentitySource` will represent.
*
* @returns a query string identity source.
*/
public static queryString(queryString: string): string {
return IdentitySource.toString(queryString, 'method.request.querystring');
}

/**
* Provides a properly formatted API Gateway stage variable identity source.
* @param stageVariable the name of the stage variable the `IdentitySource` will represent.
*
* @returns an API Gateway stage variable identity source.
*/
public static stageVariable(stageVariable: string): string {
return IdentitySource.toString(stageVariable, 'stageVariables');
}

/**
* Provides a properly formatted request context identity source.
* @param context the name of the context variable the `IdentitySource` will represent.
*
* @returns a request context identity source.
*/
public static context(context: string): string {
return IdentitySource.toString(context, 'context');
}

private static toString(source: string, type: string) {
if (!source.trim()) {
throw new Error(`IdentitySources must be a non-empty string.`);
}

return `${type}.${source}`;
}
}
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-apigateway/lib/authorizers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './lambda';
export * from './lambda';
export * from './identity-source';
Loading