オーソライザーにCognitoユーザープールを使用したAmazon API Gatewayにcurlで認証を突破する

2022.01.04

Amazon API GatewayはAmazon Cognitoユーザープールとシームレスに連携出来ます。

今回は、コマンドライン操作のサンプルとして、curl だけを使い API Gateway(REST版) の Cognito 認証を突破する方法を紹介します。

前提

Cognitoユーザープールを作成し、 General settings -> App clients -> Enable username password based authentication (ALLOW_USER_PASSWORD_AUTH) をチェックしてください。

Cognito ユーザーを新規作成し、初期パスワードの変更を済ませておいてください(account status = CONFIRMED)。

curl の認証フロー

以下の流れで API Gatewayにリクエストします。

  1. Cognitoユーザープールに USER_PASSWORD_AUTH フローで認証
  2. Cognito トークン を取得
  3. API GatewayにIDトークンを Authorization ヘッダーで渡す

1. Cognito IdP に認証

USER_PASSWORD_AUTH フローで Cognito IdP 認証を開始(InitiateAuth)します。

そのために、以下の内容のファイル(auth.json)を用意します。

auth.json

{
  "ClientId" : "COGNITO_CLIENT_ID",
  "AuthFlow" : "USER_PASSWORD_AUTH",
  "AuthParameters": {
    "USERNAME" : "john.smith@example.com",
    "PASSWORD" : "YOUR_PASSWORD"
  }
}
  • ClientId は Cognito ユーザープールのクライアントID に合わせます
  • AuthParameters は 認証する Cognito ユーザーのメールアドレス・パスワードに合わせます

このファイルを引数にして Cognito IdP のエンドポイントに認証の開始(InitiateAuth) をリクエストし、Cognitoユーザープールの JWTを取得します。

$ curl -X POST \
  -H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
  -H 'Content-Type: application/x-amz-json-1.1' \
  --data @auth.json \
  https://cognito-idp.リージョン.amazonaws.com/

{
  "AuthenticationResult": {
    "AccessToken": "eyJra...",
    "ExpiresIn": 3600,
    "IdToken": "eyJra...",
    "RefreshToken": "eyJj...",
    "TokenType": "Bearer"
  },
  "ChallengeParameters": {}
}
$ IdToken="eyJr..."

JWTに含まれるIDトークンを取得します。

IDトークンはワンライナーでも取得出来ます。

$ IdToken=$(curl -s -X POST \
  -H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
  -H 'Content-Type: application/x-amz-json-1.1' \
  --data @auth.json \
  https://cognito-idp.ap-northeast-1.amazonaws.com/ | jq -r .AuthenticationResult.IdToken)

2. API GatewayにIDトークンでリクエスト

API Gatewayへのリクエスト時に、IDトークンをリクエストヘッダーの Authorization に渡します。

$ curl \
  -H "Authorization: $IdToken" \
  https://xxx.execute-api.リージョン.amazonaws.com/path/to/method

GUI操作ならPostman

コマンドラインから API Gateway にリクエストしたい場合、スクリプトを組むなり、今回紹介したような curl が便利です。

GUIでアドホックにリクエストしたい場合、Postman の利用をご検討ください。

それでは。

参照