Traffine I/O

日本語

2022-10-05

Amazon S3における署名済みURL

署名済みURLとは

署名済みURL(Presigned URL)は、Amazon S3が提供するユニークな機能であり、S3バケット内のプライベートオブジェクトへの一時的かつ安全なアクセスを可能にします。これらのURLは、必要な認証情報を含み、S3バケットのオーナーのAWSセキュリティ資格情報を使用して生成されます。

要するに、署名済みURLは、Amazon S3内のオブジェクトのURLに、セキュリティ資格情報と有効期限の追加パラメータが付加されたものです。このURLが生成されると、それを受け取った人はオブジェクトにアクセスするために使用できます。これは、オブジェクトがプライベートでありユーザーにはアクセスできない場合でも有効です。

Presigned URL
AWS S3 Presigned URL Upload Tutorial in Python

署名済みURLのユースケース

署名済みURLは、さまざまなユースケースに効果的なソリューションを提供します。それらを使用する主な理由の一つは、プライベートオブジェクトへの一時的なアクセスを提供する必要がある場合です。例えば、ファイルを他の人と共有する必要があるが、オブジェクトのアクセス許可を変更したり、複雑なアクセス制御リストを管理する必要はない場合に便利です。

もう一つの一般的なユースケースは、AWSアカウントを持っていないユーザーがS3バケットにファイルをアップロードまたはダウンロードできるようにする場合です。例えば、アップロード操作用の署名済みURLを生成し、これをユーザーに提供します。ユーザーはこのURLを使用してファイルを直接S3バケットにアップロードでき、これによりユーザーはAWSアクセスキーを知る必要がありません。

署名済みURLは、Web開発においても重要な役割を果たします。これにより、ウェブサイトやWebアプリケーションから直接ダウンロードリンクを提供することができます。これにより、ファイルをフェッチするためのサーバーサイドのコードが必要なく、帯域幅を節約しパフォーマンスを向上させることができます。

Amazon S3での署名済みURLの操作方法

署名済みURLの生成方法は、使用している言語とAWS SDKによって異なります。この章では、Boto3として知られるPythonのAWS SDKを使用したプロセスを説明します。

ダウンロード操作の場合、以下のPythonコードで署名済みURLを生成します。

python
import boto3
from botocore.exceptions import NoCredentialsError

def create_presigned_url(bucket_name, object_name, expiration=3600):
    """Generate a presigned URL to share an S3 object

    :param bucket_name: string
    :param object_name: string
    :param expiration: Time in seconds for the presigned URL to remain valid
    :return: Presigned URL as string. If error, returns None.
    """

    # Generate a presigned URL for the S3 object
    s3_client = boto3.client('s3')
    try:
        response = s3_client.generate_presigned_url('get_object',
                                                    Params={'Bucket': bucket_name,
                                                            'Key': object_name},
                                                    ExpiresIn=expiration)
    except NoCredentialsError:
        return None

    # The response contains the presigned URL
    return response

アップロード操作の場合、次のように署名済みURLを生成できます。

python
def create_presigned_post(bucket_name, object_name, fields=None, conditions=None, expiration=3600):
    """Generate a presigned URL S3 POST request to upload a file

    :param bucket_name: string
    :param object_name: string
    :param fields: Dictionary of prefilled form fields
    :param conditions: List of conditions to include in the policy
    :param expiration: Time in seconds for the presigned URL to remain valid
    :return: Dictionary with the following keys:
        url: URL to post to
        fields: Dictionary of form fields and values to submit with the post
    """

    # Generate a presigned S3 POST URL
    s3_client = boto3.client('s3')
    try:
        response = s3_client.generate_presigned_post(bucket_name,
                                                     object_name,
                                                     Fields=fields,
                                                     Conditions=conditions,
                                                     ExpiresIn=expiration)
    except NoCredentialsError:
        return None

    # The response contains the presigned URL and required fields
    return response

適切なバケット名とオブジェクト名を使用してこのコードを実行すると、次のようなレスポンスが返されます。

{
  "url": "https://mybucket.s3.amazonaws.com/",
  "fields": {
    "key": "myobjectkey",
    "AWSAccessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "policy": "eyJleHBpcmF0aW9uIjogIjIwMjAtMDktMjlUMTk6MzA6MjBaIiwgImNv...",
    "signature": "b5cc6dc8dd2700d2a35f4e6a39c6b2b44b0215f5ecee0630..."
  }
}

このレスポンスには、クライアントがPOSTすべきURLと、POSTリクエストのフォームデータに含める必要のあるフィールドが含まれています。

参考

https://aws.amazon.com/blogs/storage/using-presigned-urls-to-identify-per-requester-usage-of-amazon-s3/
https://medium.com/@aidan.hallett/securing-aws-s3-uploads-using-presigned-urls-aa821c13ae8d
https://beabetterdev.com/2021/09/30/aws-s3-presigned-url-upload-tutorial-in-python/?noamp=mobile

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!