S3で署名付きURLを使ったアクセス制御

はじめに

S3(Simple Storage Service)では、単純なアップロード・ダウンロードだけでなく、アクセス権限の制御やバージョニングなど、様々な機能を提供しています。

今回はその中から、署名付きURLを使ってみたいと思います。

署名付きURLとは?

S3ではアクセスのポリシーをパブリックに設定したり、IAMユーザ単位での細かなアクセス制御などを行うことができます。
署名付きURLとは、その一環として、有効期限を設けて、ある特定のURLからのみアクセスできるようにするための機能です。
これを利用することで、基本はプライベートにしておいて、ポリシーを緩めることなく、一時的に他のユーザにファイルを共有したりすることが可能になります。

なお、ユーザ単位のアクセス制御ではないため、有効期限内であれば、誰でもそのURLからアクセスできるという点には注意が必要です。

試してみる

まずは適当なバケットを作成して、ファイルをアップロードしておきます。
このときパブリックアクセスを許可しないよう注意してください。

アップロードしたファイルのリンクにアクセスすると、当然アクセス拒否されます。

署名付きURLを使ってこのファイルにアクセスできるようにするのが今回の目標です。
とりあえず今回は ruby-sdk を使って、コマンドラインで署名付きURLを生成してみます。

以下のようなコードを用意します。
認証情報とバケット名、ファイル名等は適宜変更してください。

require 'aws-sdk'
resource = Aws::S3::Resource.new(
:region => 'ap-northeast-1', # 東京以外のリージョンの場合は適宜変更してください
:access_key_id => '<your access key>',
:secret_access_key => '<your secret access key>'
)
object = resource.bucket('<your bucket name>').object('<your file name>')
puts url = URI.parse(object.presigned_url(:get, expires_in: 60)) # 有効期限を1分から変更する場合は適宜変更してください。

適当な名前で保存して、コマンドラインで実行してみると・・・

$ ruby test.rb
https://20170605-presigned-url-test.s3-ap-northeast-1.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAJFM6SK4BF5JJH2BA%2F20170605%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20170605T101951Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=5c90a7378e91c618d9dbeabf0dcf3b65fe78a893c070076275944c8aa25f05d8

署名付きURLが生成されました。
有効期限を1分にしているのですぐにアクセスしてみましょう。

ちゃんと表示されましたね。
自分の環境では文字化けしてしまったので、ブラウザのエンコードをUTF-8に変更しました。

有効期限が切れるかどうかも見ておきましょう。
少し待ってからアクセスしてみます。

有効期限切れになったので、ちゃんとアクセスできなくなっていますね。
このように、簡単に署名付きURLを生成することができました。

おわりに

有効期限付きのダウンロードURLという、自前で実装するとなるとなかなか骨が折れそうな機能も簡単に実現することができました。
少し応用すると、IP制限と組み合わせて、特定ユーザのみアクセス可能なURLを生成する、なんてこともできるようです。
ちょっとした機能ではありますが、知っておくと実装の幅が広がりますね。

APN Consulting Partner
スーパーソフトウエアはAWSパートナーネットワーク(APN)のコンサルティングパートナーです。