はじめに
CloudFront + S3 の組み合わせで、S3 内のファイルへのアクセスに制限をかけたいとき、署名付き Cookie を使った制限付きアクセスを利用することがあると思います。
この記事では、AWS SDK for Ruby V3 を使って、CloudFront + S3で署名付き Cookie を生成する方法を検証した内容を備忘メモとしてまとめます。
前提環境
- S3 バケット作成済み
- S3 バケットへのフルアクセス権限のある AWS アクセスキー作成済み
- CloudFront を作成した S3 バケットをオリジンに設定して構築済み
- CloudFrontでS3制限アクセス設定済み
- CloudFront用キーペアをルートアカウントから登録し、秘密鍵を手元に控えてある
上記の前提環境を準備するにあたっての手順は、以下記事がわかりやすいのでそちらをご参照ください。
AWS CloudFront 署名付きcookieの作り方 - Qiita
署名付きCookieつくる
以下サンプルコードです。
key_pair_id = 'AKIAIOSFODNN7EXAMPLE'
pem_file = '/path/to/private_key.pem'
signer = Aws::CloudFront::CookieSigner.new(
key_pair_id: key_pair_id,
private_key_path: pem_file
)
url = 'https://xxxxxxxxxxxxxx.cloudfront.net'
policy_statement = {
"Statement" => [
{
"Resource" => "http*://xxxxxxxxxxxxxx.cloudfront.net/*",
"Condition" => {
"DateLessThan":
{
"AWS:EpochTime" => 1.hours.since.to_i
}
}
}
]
}
cookies = signer.signed_cookie(url,
policy: policy_statement.to_json
)
Aws::CloudFront::CookieSigner
を使い、CloudFront の署名付き Cookie を作成するためのオブジェクトを生成しています。必要なのは CloudFront キーペアの ID と秘密鍵のファイルパスです。
signed_cookie
メソッドで、CloudFront のカスタムポリシーのステートメントを設定し、署名付き Cookie を生成しています。ポリシーステートメントでは、CloudFront でのアクセス可能なリソース範囲、Cookieの有効期限(エポック秒)で指定しています。
実行すると、以下のようなハッシュが生成されます。
{"CloudFront-Policy"=>
"XXXXXX",
"CloudFront-Signature"=>
"XXXXXX",
"CloudFront-Key-Pair-Id"=>"AKIAIOSFODNN7EXAMPLE"}
動作確認
生成したハッシュを使ってgetリクエストを投げてみましょう。設定有無でオブジェクトが取得できているかどうかが変わっていることが確認できます。
require 'open-uri'
cookies_str = cookies.map{|x|x.join('=')}.join('; ')
file = open('https://xxxxxxxxxxxxxx.cloudfront.net/test.txt', { 'Cookie' => cookies_str })
おわりに
Ruby のメソッド経由であれば、署名付き Cookie の有効期限を動的に変更するのも簡単なので使いやすいなと思いました。