|
| 1 | +# Lambda Authorizer with API Gateway |
| 2 | + |
| 3 | +This is an example of a Lambda Authorizer function. There are two Lambda functions in this example. The first one is the authorizer function. The second one is the business function. The business function is exposed through a REST API using the API Gateway. The API Gateway is configured to use the authorizer function to implement a custom logic to authorize the requests. |
| 4 | + |
| 5 | +>[!NOTE] |
| 6 | +> If your application is protected by JWT tokens, it's recommended to use [the native JWT authorizer provided by the API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html). The Lambda authorizer is useful when you need to implement a custom authorization logic. See the [OAuth 2.0/JWT authorizer example for AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-controlling-access-to-apis-oauth2-authorizer.html) to learn how to use the native JWT authorizer with SAM. |
| 7 | +
|
| 8 | +## Code |
| 9 | + |
| 10 | +The authorizer function is a simple function that checks data received from the API Gateway. In this example, the API Gateway is configured to pass the content of the `Authorization` header to the authorizer Lambda function. |
| 11 | + |
| 12 | +There are two possible responses from a Lambda Authorizer function: policy and simple. The policy response returns an IAM policy document that describes the permissions of the caller. The simple response returns a boolean value that indicates if the caller is authorized or not. You can read more about the two types of responses in the [Lambda authorizer response format](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html) section of the API Gateway documentation. |
| 13 | + |
| 14 | +This example uses an authorizer that returns the simple response. The authorizer function is defined in the `Sources/AuthorizerLambda` directory. The business function is defined in the `Sources/APIGatewayLambda` directory. |
| 15 | + |
| 16 | +## Build & Package |
| 17 | + |
| 18 | +To build the package, type the following commands. |
| 19 | + |
| 20 | +```bash |
| 21 | +swift build |
| 22 | +swift package archive --allow-network-connections docker |
| 23 | +``` |
| 24 | + |
| 25 | +If there is no error, there are two ZIP files ready to deploy, one for the authorizer function and one for the business function. |
| 26 | +The ZIP file are located under `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager` |
| 27 | + |
| 28 | +## Deploy |
| 29 | + |
| 30 | +The deployment must include the Lambda functions and the API Gateway. We use the [Serverless Application Model (SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) to deploy the infrastructure. |
| 31 | + |
| 32 | +**Prerequisites** : Install the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) |
| 33 | + |
| 34 | +The example directory contains a file named `template.yaml` that describes the deployment. |
| 35 | + |
| 36 | +To actually deploy your Lambda function and create the infrastructure, type the following `sam` command. |
| 37 | + |
| 38 | +```bash |
| 39 | +sam deploy \ |
| 40 | +--resolve-s3 \ |
| 41 | +--template-file template.yaml \ |
| 42 | +--stack-name APIGatewayWithLambdaAuthorizer \ |
| 43 | +--capabilities CAPABILITY_IAM |
| 44 | +``` |
| 45 | + |
| 46 | +At the end of the deployment, the script lists the API Gateway endpoint. |
| 47 | +The output is similar to this one. |
| 48 | + |
| 49 | +``` |
| 50 | +----------------------------------------------------------------------------------------------------------------------------- |
| 51 | +Outputs |
| 52 | +----------------------------------------------------------------------------------------------------------------------------- |
| 53 | +Key APIGatewayEndpoint |
| 54 | +Description API Gateway endpoint URI |
| 55 | +Value https://a5q74es3k2.execute-api.us-east-1.amazonaws.com/demo |
| 56 | +----------------------------------------------------------------------------------------------------------------------------- |
| 57 | +``` |
| 58 | + |
| 59 | +## Invoke your Lambda function |
| 60 | + |
| 61 | +To invoke the Lambda function, use this `curl` command line. Be sure to replace the URL with the API Gateway endpoint returned in the previous step. |
| 62 | + |
| 63 | +When invoking the Lambda function without `Authorization` header, the response is a `401 Unauthorized` error. |
| 64 | + |
| 65 | +```bash |
| 66 | +curl -v https://a5q74es3k2.execute-api.us-east-1.amazonaws.com/demo |
| 67 | +... |
| 68 | +> GET /demo HTTP/2 |
| 69 | +> Host: 6sm6270j21.execute-api.us-east-1.amazonaws.com |
| 70 | +> User-Agent: curl/8.7.1 |
| 71 | +> Accept: */* |
| 72 | +> |
| 73 | +* Request completely sent off |
| 74 | +< HTTP/2 401 |
| 75 | +< date: Sat, 04 Jan 2025 14:03:02 GMT |
| 76 | +< content-type: application/json |
| 77 | +< content-length: 26 |
| 78 | +< apigw-requestid: D3bfpidOoAMESiQ= |
| 79 | +< |
| 80 | +* Connection #0 to host 6sm6270j21.execute-api.us-east-1.amazonaws.com left intact |
| 81 | +{"message":"Unauthorized"} |
| 82 | +``` |
| 83 | + |
| 84 | +When invoking the Lambda function with the `Authorization` header, the response is a `200 OK` status code. Note that the Lambda Authorizer function is configured to accept any value in the `Authorization` header. |
| 85 | + |
| 86 | +```bash |
| 87 | +curl -v -H 'Authorization: 123' https://a5q74es3k2.execute-api.us-east-1.amazonaws.com/demo |
| 88 | +... |
| 89 | +> GET /demo HTTP/2 |
| 90 | +> Host: 6sm6270j21.execute-api.us-east-1.amazonaws.com |
| 91 | +> User-Agent: curl/8.7.1 |
| 92 | +> Accept: */* |
| 93 | +> Authorization: 123 |
| 94 | +> |
| 95 | +* Request completely sent off |
| 96 | +< HTTP/2 200 |
| 97 | +< date: Sat, 04 Jan 2025 14:04:43 GMT |
| 98 | +< content-type: application/json |
| 99 | +< content-length: 911 |
| 100 | +< apigw-requestid: D3bvRjJcoAMEaig= |
| 101 | +< |
| 102 | +* Connection #0 to host 6sm6270j21.execute-api.us-east-1.amazonaws.com left intact |
| 103 | +{"headers":{"x-forwarded-port":"443","x-forwarded-proto":"https","host":"6sm6270j21.execute-api.us-east-1.amazonaws.com","user-agent":"curl\/8.7.1","accept":"*\/*","content-length":"0","x-amzn-trace-id":"Root=1-67793ffa-05f1296f1a52f8a066180020","authorization":"123","x-forwarded-for":"81.49.207.77"},"routeKey":"ANY \/demo","version":"2.0","rawQueryString":"","isBase64Encoded":false,"queryStringParameters":{},"pathParameters":{},"rawPath":"\/demo","cookies":[],"requestContext":{"domainPrefix":"6sm6270j21","requestId":"D3bvRjJcoAMEaig=","domainName":"6sm6270j21.execute-api.us-east-1.amazonaws.com","stage":"$default","authorizer":{"lambda":{"abc1":"xyz1"}},"timeEpoch":1735999482988,"accountId":"401955065246","time":"04\/Jan\/2025:14:04:42 +0000","http":{"method":"GET","sourceIp":"81.49.207.77","path":"\/demo","userAgent":"curl\/8.7.1","protocol":"HTTP\/1.1"},"apiId":"6sm6270j21"},"stageVariables":{}} |
| 104 | +``` |
| 105 | + |
| 106 | +## Undeploy |
| 107 | + |
| 108 | +When done testing, you can delete the infrastructure with this command. |
| 109 | + |
| 110 | +```bash |
| 111 | +sam delete --stack-name APIGatewayWithLambdaAuthorizer |
| 112 | +``` |
0 commit comments