Created
June 6, 2023 08:19
-
-
Save coisme/a47f9ceed259bc7e2c6142d1bf690d4b to your computer and use it in GitHub Desktop.
Signed request sample for API Gateway
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
# | |
# Signed request sample script for API Gateway | |
# | |
# @Author: Osamu Koizumi | |
# | |
# Official Document: | |
# Create a signed AWS API request | |
# https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html | |
# | |
# Prerequisites: | |
# - Create an API Gateway resource by following this page: | |
# https://qiita.com/ita-k/items/5d6e8ceaf3f0a970b594 | |
# and get the following parameters. | |
# * Access Key ID | |
# * Secret Access Key | |
# * Invoke URL (incl. host, service, region, and stage name.) | |
# | |
# Tested on: | |
# macOS 13.3.1 | |
# OpenSSL 3.0.0 7 sep 2021 (Library: OpenSSL 3.0.0 7 sep 2021) | |
# curl 7.87.0 | |
# User setting | |
# | |
# From IAM console | |
AWS_ACCESS_KEY="YOUR_ACCESS_KEY" | |
AWS_SECRET_ACCESS_KEY="YOUR_SECRET_ACCESS_KEY" | |
# From API Gateway Invoke URL | |
HOST="**********.execute-api.ap-northeast-1.amazonaws.com" | |
SERVICE="execute-api" | |
REGION="ap-northeast-1" | |
STAGE_NAME="test" | |
# Enable debug print: 1 - enable, other values - disable | |
DEBUG=0 | |
# | |
# Step 1: Create a canonical request | |
# | |
PAYLOAD="" | |
CURRENT_DATETIME=`date -u +'%Y%m%dT%H%M%SZ'` | |
HTTP_METHOD="GET" | |
CANONICAL_URI="/${STAGE_NAME}" | |
CANONICAL_QUERY_STRING="" | |
CANONICAL_HEADERS="host:${HOST} | |
x-amz-date:${CURRENT_DATETIME} | |
" | |
SIGNED_HEADERS="host;x-amz-date" | |
HASHED_PAYLOAD=`echo -n ${PAYLOAD} \ | |
| openssl dgst -sha256 -hex \ | |
| sed 's/^.* //'` | |
CANONICAL_REQUEST="${HTTP_METHOD} | |
${CANONICAL_URI} | |
${CANONICAL_QUERY_STRING} | |
${CANONICAL_HEADERS} | |
${SIGNED_HEADERS} | |
${HASHED_PAYLOAD}" | |
if [[ ${DEBUG} -eq 1 ]] then | |
echo "=== Canonical request ===" | |
echo "${CANONICAL_REQUEST}" | |
echo "=== /Canonical request ===" | |
fi | |
# | |
# Step 2: Create a hash of the canonical request | |
# | |
HASHED_CANONICAL_REQUEST=`echo -n "${CANONICAL_REQUEST}" \ | |
| openssl dgst -sha256 -hex \ | |
| sed 's/^.* //'` | |
# | |
# Step 3: Create a string to sign | |
# | |
CURRENT_DATE=`echo -n ${CURRENT_DATETIME} | awk -F'T' '{print $1}'` | |
ALGORITHM="AWS4-HMAC-SHA256" | |
REQUEST_DATETIME=${CURRENT_DATETIME} | |
CREDENTIAL_SCOPE="${CURRENT_DATE}/${REGION}/${SERVICE}/aws4_request" | |
STRING_TO_SIGN="${ALGORITHM} | |
${REQUEST_DATETIME} | |
${CREDENTIAL_SCOPE} | |
${HASHED_CANONICAL_REQUEST}" | |
if [[ ${DEBUG} -eq 1 ]] then | |
echo "=== String to sign ===" | |
echo "${STRING_TO_SIGN}" | |
echo "=== /String to sign ===" | |
echo | |
fi | |
# | |
# Step 4: Calculate the signature | |
# | |
K_DATE=`echo -n "${CURRENT_DATE}" \ | |
| openssl dgst -sha256 -hex -hmac "AWS4${AWS_SECRET_ACCESS_KEY}" \ | |
| sed 's/^.* //'` | |
K_REGION=`echo -n "${REGION}" \ | |
| openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${K_DATE}" \ | |
| sed 's/^.* //'` | |
K_SERVICE=`echo -n "${SERVICE}" \ | |
| openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${K_REGION}" \ | |
| sed 's/^.* //'` | |
K_SIGNING=`echo -n "aws4_request" \ | |
| openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${K_SERVICE}" \ | |
| sed 's/^.* //'` | |
SIGNATURE=`echo -n "${STRING_TO_SIGN}" \ | |
| openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${K_SIGNING}" \ | |
| sed 's/^.* //'` | |
if [[ ${DEBUG} -eq 1 ]] then | |
echo "=== Signature ===" | |
echo "signature: ${SIGNATURE}" | |
echo "=== /Signature ===" | |
fi | |
# | |
# Step 5: Add the signature to the request | |
# | |
# Without signature | |
# Expected result: | |
# {"message":"Missing Authentication Token"} | |
echo "Request without signature (fail)" | |
curl -X GET "https://${HOST}/${STAGE_NAME}" | |
echo "\n" | |
# With signature | |
# Expected result (depends on implementation of Lambda function): | |
# {"statusCode": 200, "body": "\"Hello from Lambda!\""} | |
echo "Request with signature (success)" | |
curl -X GET \ | |
-H "Host: ${HOST}" \ | |
-H "X-Amz-Date: ${CURRENT_DATETIME}" \ | |
-H \ | |
"Authorization: AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY}/"\ | |
"${CREDENTIAL_SCOPE}, SignedHeaders=${SIGNED_HEADERS},"\ | |
"Signature=${SIGNATURE}" \ | |
"https://${HOST}/${STAGE_NAME}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment