11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Cognitoを使って公開されていないS3バケットからファイルを取得する

Posted at

やりたいこと

  • S3のバケットをWebホスティング用に設定することなく、モバイルアプリケーションにバケット内のオブジェクトをダウンロードさせたい。
  • ユーザー登録やログインのようなユーザー管理は行わない

モバイルアプリでCognitoを使って匿名ユーザーとして認証を行い、一時的なキーを作成する。このキーにはS3からのダウンロード権限のみを与え、モバイルアプリはキーを使うことでS3からオブジェクトをダウンロードすることができるようになる。

準備

Identity pool を作成する

Identity poolとはCognitoが作成する認証キーが保存されるところです。ここで何個のキーが発行されたかを確認したり、個別のキーを削除したりすることが可能です。

Identity poolにはIAMロールを関連付けます。Cognitoで作成された認証キーはこのIAMロールによってアクセス可能なAWSリソースを制限されます。
関連付けるIAMロールはUnauthenticated roleとAuthenticated roleの2種類があり、匿名認証時とID認証時で必要な権限を分けることができます。両方ともに同じロールを指定することも可能です。

ロールを作成する

Identity poolを作成する時に関連付けるIAMロールを設定します。先にIAMロールを作っておいて設定することもできますし、Identity poolを作成するプロセスの中でIAMロールを作成することもできます。

どちらの場合でも適切に必要最低限の機能のみを与えるようにすることが重要です。
今回の例としてmy-test-bucketというバケット内の全てのオブジェクトについて取得のみの権限を与えることを考えます。このようなロールは以下のように設定します。
なお、Statementの一つ目の要素は最初から設定されている権限で、モバイルアナリティクスやCognito同期機能で使用する権限なので、そのまま残してあります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-test-bucket/*"
            ]
        }
    ]
}

Identity poolが作成できたら、次はアプリケーション側の実装です。
以下はAndroid Studioでの作業手順です。

Dependencyを追加

app/build.gradleのdependenciesブロックに以下の記述を追加します。

app/build.gradle
dependencies {
    compile 'com.amazonaws:aws-android-sdk-core:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-s3:2.2.+'
}

パーミッションを追加

S3と通信をするためにもちろんインターネットパーミッションが必要です。ドキュメントには書いてなかったのですがandroid.permission.ACCESS_NETWORK_STATEもないとエラーになりました。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Java

ここからはJavaの実装になります。
Cognitoを使用して認証キーを取得するためにはまずCognitoCachingCredentialsProviderインスタンスを作成します。IDENTITY_POOL_IDは実際のIdentity poolのIDに置き換えてください。この値はAWSコンソールでCognito→Manage Federated Identities→Identity pool名をクリック→Edit identity poolと辿ると確認できます。

CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
    getApplicationContext(),
    IDENTITY_POOL_ID,
    Regions.AP_NORTHEAST_1 // Region
);

次に、作成したCognitoCachingCredentialsProviderを使ってAmazonS3Clientインスタンスを作成します。

AmazonS3Client s3 = new AmazonS3Client(credentialsProvider);

S3からファイルをダウンロードするには、TransferUtilityを使います。

TransferUtility transferUtility = new TransferUtility(s3, getApplicationContext());
TransferObserver observer = transferUtility.download("bucketName", "objectName", targetFile);

まとめると以下のような感じになります。

CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
        getApplicationContext(),
        IDENTITY_POOL_ID, // 実際のIdentity poolに置き換える
        Regions.AP_NORTHEAST_1);

AmazonS3Client s3 = new AmazonS3Client(credentialsProvider);
TransferUtility transferUtility = new TransferUtility(s3, getApplicationContext());

String bucketName = "my-test-bucket";
String fileName = "test.jpg";
File file = new File(getFilesDir(), fileName);

TransferObserver observer = transferUtility.download(bucketName, fileName, file);
observer.setTransferListener(new TransferListener() {
    @Override
    public void onStateChanged(int id, TransferState state) {
        switch (state) {
            case COMPLETED:
                // ダウンロード完了時
                break;
        }
    }

    @Override
    public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
    }

    @Override
    public void onError(int id, Exception ex) {
    }
});
11
7
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
11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?