🐟

CognitoのIDプールの未認証ユーザを使ってS3の特定ディレクトリにアクセスする

2023/08/22に公開

はじめに

CognitoのIDプールの機能に、「認証されていないIDに対してアクセスを有効化する」機能、すなわち未認証のゲストユーザに対して、AWSのリソースに対するアクセス権を付与する機能があります。
この記事ではその機能を使って、未認証のユーザがS3の特定のディレクトリにアクセスする方法を紹介したいと思います。

そんなことせずに、S3を公開バケットにしちゃえば良いのでは?と思われるかもしれませんが、いくら機密を含まないファイルであっても、アプリを使用しない第三者にはなるべくオープンにしたくない(例えば不必要にファイルに大量アクセスされるなどの攻撃を防ぎたい)というケースは多いかと思います。

CognitoのIDプールって何?という方は以下の公式ドキュメントを参照ください。

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/identity-pools.html

前提として、CognitoのユーザプールとIDプールはAmplifyなどを使ってすでに作成済みの状態&言語はTypeScriptとします。

やること

Cognito IDプールの設定

IDプールの編集 → 「認証されていない ID に対してアクセスを有効にする」 にチェックを入れます。

※最近、コンソールの画面が新しくなって、操作方法が変わったようです。
新バージョンのコンソールの場合の手順は以下を参照ください。

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/identity-pools.html#enable-or-disable-unauthenticated-identities

unAuthRoleの設定

amplifyでcognitoを作成した場合、unAuthRoleというIAMロールが作成されているので、そのロールに対して、S3の特定のディレクトリに対してアクセスする権限を付与します。

以下、例です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name/public/*"
            ],
            "Effect": "Allow"
        }
    ]
}

aws sdkを使ってS3にアクセス

上記で定義したロールを引き受けて、S3にアクセスします。
以下のように、cognitoのIDプールのIDさえ知っていれば、ロールを引き受けることが可能です。

import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers';

const testFunction = async () => {
  const client = new S3Client({
    region: 'ap-northeast-1',
    credentials: fromCognitoIdentityPool({
      identityPoolId: 'IDプールのID',
      clientConfig: {
        region: 'ap-northeast-1',
      },
    }),
  });

  const command = new GetObjectCommand({
    Bucket: 'bucket-name',
    Prefix: 'public/',
  });

  await client.send(command);
};

参考にさせていただいた記事

https://zenn.dev/kzen/articles/392bf636fdddb5

Discussion