1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

API Gateway でIAM認証を通してみた!Postman、AWS CDK

Last updated at Posted at 2024-05-07

きっかけ

とあるプロジェクトで使った別で作成された既存のAPIを実行するのにIAM認証が有効になっていたためIAMが必要だったのですが、これまでAPIキーでしか認証を通したことがなかったため実装するのに悪戦苦闘しました。
色々調べてうまく行ったのでここにまとめてみました。

やりたいこと

  1. CDKから作成しているラムダ関数から別で作成されたIAM認証を通してAPIを実行する
  2. postmanからAPIの動作確認をしたいためpostmanでのIAM認証設定

ラムダ関数の設定

CDKでの権限設定

ラムダはこのように定義しました⇩

cdk/lib/lambda.ts
const lambda = new lambda.Function(
  this,
  `lambda-${props.envName}`,
  {
    runtime: Runtime.NODEJS_18_X,
    handler: 'index.handler',
    code: lambda.Code.fromAsset('lambda/'), // ラムダコードのパス
    environment: { // ラムダの環境変数
      REGION: this.region,
      apiGatewayEndpoint: props.apiGatewayEndpoint,
    },
    timeout: Duration.seconds(900),
    layers: [lambdaLayer], // ラムダレイヤーの設定
  }
);

ラムダのIAMにAPIを実行可能にするポリシーをロールに追加する必要があるので、CDKでこのように取り付けました。

cdk/lib/lambda.ts
lambda.role?.addManagedPolicy(
  iam.ManagedPolicy.fromAwsManagedPolicyName(
    'AmazonAPIGatewayInvokeFullAccess'
  )
);

これでCDKの方で必要な権限まわりの設定は完了です!

ラムダのコードでIAM認証する方法

lambda/credential.ts
import { SignatureV4 } from '@aws-sdk/signature-v4';
import { defaultProvider } from '@aws-sdk/credential-provider-node';
import { Sha256 } from '@aws-crypto/sha256-js';
import { HttpRequest } from '@aws-sdk/protocol-http';

export const getSignedHttpRequest = async (url: string, body: object) => {
  const serviceName = 'execute-api'; // APIを実行するため
  const parts = url.split('?');

  const host = parts[0].substring(8, parts[0].indexOf('/', 8));
  const path = parts[0].substring(parts[0].indexOf('/', 8));

  const req = new HttpRequest({
    headers: {
      host,
    },
    protocol: 'https:',
    hostname: host,
    method: 'POST', //実行したいAPIのメソッドに変える
    path: path,
    body: JSON.stringify(body),
  });

  const signer = new SignatureV4({
    credentials: defaultProvider(), //自動的にラムダのアクセスキーとシークレットキーを使って認証コードを発行してくれます
    region: process.env.envName
    service: serviceName,
    sha256: Sha256,
  });
  const signedHttpRequest = await signer.sign(req);

  return signedHttpRequest;
};

これで設定完了です!ラムダからAPI実行できるようになると思います。

注意点
cdkもしくはマネコンからラムダのロールにAPIを実行するポリシーを付与できていないと

"User: arn:aws:iam::*:user/api-unvalid is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api...."
というエラーが出てしまうので注意です。

Postmanの設定

  1. ポストマンのAuthorizationタグをクリックします
  2. TypeでAWS Signatureを選択します。
  3. コンソールから作成したAccessKeySecreteKeyを貼り付けます。(APIInvocationの権限を付与したもの)
  4. AWS Regionを設定する。東京の場合はap-northeast-1になります。
    スクリーンショット 2024-05-07 16.13.21.png

これで設定完了です!PostmanからもAPI実行できるようになりました!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?