@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt
Version:
Add a lambda function to your aws-rest-api-gateway which can be used as a token authorizer
172 lines (129 loc) ⢠7.5 kB
Markdown
Add a lambda function to your project which can be used as a apigateway token authorizer
[](https://constructs.dev/packages/@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt)
[](https://github.com/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt/blob/main/LICENSE)
[](https://github.com/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt/releases)
[](https://www.npmjs.com/package/@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt)
[](https://pypi.org/project/cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt/)
[](https://www.nuget.org/packages/CloudyWithAchanceOfMeatballs.CdkLambdaTokenAuthorizerJwt/)
[](https://github.com/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt/actions/workflows/release.yml)
[](https://codeclimate.com/github/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt/maintainability)
[](https://codecov.io/gh/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt)
[](https://gitpod.io/#https://github.com/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt)
## Install
### TypeScript
```shell
npm install @cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt
```
### Python
```shell
pip install cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt
```
## Usage
### Notes
- **JWT Token handling**: The token verfification is done via [https://github.com/auth0/node-jsonwebtoken](https://github.com/auth0/node-jsonwebtoken), the jwks fetcher is using [https://github.com/auth0/node-jwks-rsa](https://github.com/auth0/node-jwks-rsa). The implementation per default verifies the token and if given the expiration.
- **JWT Payload:** Any verification of the token payload must be done over injecting a json schema for validation using [https://ajv.js.org/json-type-definition.html](https://ajv.js.org/json-type-definition.html).
- **Protocols:** [main/API.md#iauthorizeroptions](https://github.com/cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt/blob/main/API.md#iauthorizeroptions-)
### Example usage with Rest Apigateway
```typescript
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
export class HelloworldStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const api = new apigateway.RestApi(this, 'ApiName', {});
const tokenAuthFunction = new TokenAuthorizerJwtFunction(this, 'fnName', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'argument',
secret: 'mySecret-symmetric-or-asymmetric',
},
},
});
const tokenAuthorizer = new apigateway.TokenAuthorizer(this, 'fnNameApiGwAuthorizer', {
handler: tokenAuthFunction // use the TokenAuthorizerJwtFunction
});
const dummyFn = new lambda.Function(this, 'helloWorldFunction', {
handler: 'index.handler',
code: lambda.Code.fromInline(`exports.handler = async (event) => { console.log('event: ', event); return '{"statusCode": 200, "message": "DummyLambdaFunction"}' };`),
runtime: lambda.Runtime.NODEJS_16_X,
});
const dummyLambdaIntegration = new apigateway.LambdaIntegration(
dummyFn, { passthroughBehavior: apigateway.PassthroughBehavior.WHEN_NO_MATCH }
);
const someMethod = api.root.addMethod("GET", dummyLambdaIntegration, {
authorizer: tokenAuthorizer
});
}
}
```
```typescript
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const myValidation = { properties:{ iss: { enum: ['my_trusted_iss'] } }};
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
payloadValidationStrategy: {
strategyName: 'schema',
schema: JSON.stringify(myValidation)
},
verificationStrategy: { strategyName: 'argument', secret: 'someSecret' }
}
});
```
```typescript
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'jwksFromUriByKid',
uri: 'uri',
kid: 'kid',
}
}
});
```
```typescript
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const myPublicKeyOneliner = '-----BEGIN PUBLIC KEY---\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKuTfz7kpJHPrmcmgx4Xf4GMoM2kK4mh\nMpSOW3qu1zZA1wfMHV8PS0Kds0nXMB6mmHk/Ke1\Et68aEspQRIn1aLcCAwEAAQ==\n-----END PUBLIC KEY-----';
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'argument',
secret: myPublicKeyOneliner
}
}
});
```
<small>**Attention:** the key might be exposed during deploy, in the runtime etc.</small>
```typescript
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const mySymmetricSecret = 'sharedSecret';
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'argument',
secret: mySymmetricSecret
}
}
});
```
š»