FunctionsでS3バケット内のリソースのアクセス認証を掛ける方法タコつぼの中でプログラミングをコツコツ楽しむ人のためのやや偏ったブログです。当ページには【広告/PR】を含む場合があります。Control)」を使ったS3バケット内リソースのアクセス制限の方法を解説していました。【AWS使い方ガイド】CloudFrontからOAI/OACを利用してアクセス制限付きのS3からリソースを取得する方法CloudFlontのOAI・OACを使ってS3リソースにアクセス制限を行うおさらいになりますが、OACによるS3のアクセス制限はエンドユーザーからのS3の直接のアクセスからリソースを保護するための施策です。こんにちは!このファイルへは、CloudFrontからは自由にアクセスできます。https://xxxxxxxxxxxxx.cloudfront.net/greeting.txtこんにちは!しかし、S3バケットのリソースURLへ直接アクセスは制限されます。Denied</Message><RequestId>*********</RequestId><HostId>************</HostId></Error>こうすることでユーザーへのファイル供給をCloudFrontに一本化することはできますが、このままだと不特定多数のユーザーがアクセスすることになります。2.0)」(以降CF2)によるアクセス認証の基本を説明していきます。2.0)の話まずは簡単にCF2の使い方に触れてみます。Functions(CF2)」は、よくLambda@Edge(L@E)と比較されますが、基本的にはL@Eから様々なライブラリを削って、シンプルな機能だけを持たせた"超軽量版ローカルLambda"と考えられます。中身はLambdaのー種類とはいえ、実際はCloudFrontの機能の一部で、利用するにもCloudFront側で設定する必要があります。細かく見ていくと色々とありますが、CF2の開発者が特に考慮したいことは以下の3点です。Runtime(JR)については、v2.0になったおかげで、文法面で制約のあったv1.0からとても記述しやすくなりました。request;}と、ほぼモダンなJavascriptコードとして実装できます。CF2を使う大きなメリットとして、関数アタッチ先のCFディストリビューションと同じリージョンにすることができます。L@Eだと"us-east-1"に作成する必要があり、他のリージョンに構築したサービスと機能連帯させるにはどうしても「リージョンまたぎ」になります。リージョンまたぎ問題は、不要になったときの消し忘れだったり、デプロイバージョンに変わるARN値の指定変更作業だったり、何かとうっかりミスの原因にもなります。CF2を使うことで、こういった細かな関数の管理も気にせずに利用できます。してオリジンリクエストとオリジンレスポンスの関数タイプはL@Eしか利用できないため、今後のCF2の機能アップデートに期待です。CF2のリクエストにはBody(ペイロード)が存在しない個人的にはビューアーリクエスト型でCF2を使うことがほとんどですが、L@Eのイベントリクエスト型とは異なるため、CF2を採用するにはいくつかの注意点があります。その最たるものが、CF2のイベントリクエスト型では、「Body(ペイロード部)」が存在しない点です。イベント構造CF2のリクエストイベントには、以下のプロパティフィールドが含まれています。ヘッダーの内、Cookieヘッダーから取得されたものCF2でBodyが制限されているのは、内部メモリが2MBしかないため、それなりの大きさのデータが送り出されるとそもそも処理できるはずがない、という設計面を考慮した構造になっています。よって、POSTやPUTメソッドで送り出されたデータペイロードをCF2で処理することは現状不可能であることは最初の内に頭に入れておく必要があります。Servicesのしくみと技術がこれ1冊でしっかりわかる教科書URLのクエリ文字列からパスコードを渡す方法CF2の概要はこの辺にして、ここからはS3リソースのアクセス制限機能を実装して試してみましょう。前準備として、前回説明した手順のように、適当なCFディストリビューションでS3バケットをOACで保護するところまで行ってください。[関数を作成]をクリックします。適当な名前で関数をJR2.0で作成します。作成した関数の中身を編集していきます。[関数コード]のコード欄にコードを貼り付け、[変更を保存]で保存します。ここで使うサンプルコードとして、以下のようなものを使います。request;}CF2関数が未発行のままだと、テストも出来ないので、[発行]タブから、[関数を発行]をクリックします。次にテストを行います。以下のテストスニペットを貼り付けて、[保存]します。}}では[関数をテスト]ボタンを押してテストを開始してみます。Unauthorizedのレスポンスが返ってきています。クエリ文字列でtoken=aaaaaとパスコードと異なる値で試したのでこれは期待通りです。同じ要領で、JSONスニペットでtoken=HOGE(パスコードと一致)にして再度関数をテストしてみると、これも期待通りに、認証してアクセスを通してくれていることが分かります。これでCF2の動作確認が終わったので、この関数をCFディストリビューションへ紐付けします。[ビヘイビアを作成]からビヘイビアを追加します。Functions、関数ARNに先程のCF2関数を指定して、[ビヘイビアを作成]で確定します。CFディストリビューションの変更が反映されデプロイされるのを待って、早速認証が有効になったか、外部からアクセスを試してみます。認証トークンを含むクエリがなかったり、間違っていたりする場合の応答を確認します。401...ちゃんと401に応答していることが分かります。パスコードが一致した場合はどうでしょうか。text/plain...こんにちは!今度はちゃんとファイルにアクセス出来ています。先程のやり方だと、認証情報をもったクエリ文字列のパラメーターが第三者に読み取られる可能性もあり、あまりセキュアな方法とは言えません。ヘッダーに認証用のトークンを付与する仕組みには、「Authorization」ヘッダーがあり、これを使うことでブラウザ側に特別な扱いを行うように仕向けることができます。「Authorization」には主にBasic認証とBearer認証の2つが使われることが多いですが、今回のように自前で認証用のロジックを構築するために「Authorization」を使ってしまうと、別に使っている認証用のサービスやライブラリー(Bearerの場合がほとんど)と競合する恐れもあります。AuthorizationがどのサービスやAPIと競合するかどうかに配慮しながら開発するくらいなら、独自に認証用のヘッダーを作るほうが懸命と言えます。いうことで、「X-Auth-Token」という名前のヘッダーをオレオレ認証用に使ってみましょう。CF2関数の設定手順は先程の節と全く同じですので、同じ説明は割愛し、CF2関数の中身だけを以下に交換します。request;}先程のコードから変わったところは、リクエストオブジェクトからのヘッダーを値を引き出すのに、request.headers['x-auth-token']としているところくらいです。注意すべきなのは、コード内で利用するヘッダー名は小文字に変換する必要があります。X-Auth-Tokenはx-auth-tokenと直す必要があります。他は至って先程のクエリ文字列の場合でやったことを同じです。このCF2関数をCFディストリビューションに割り当てて、外部からアクセスを試してみましょう。text/plain...こんにちは!いい感じにアクセス制限が出来ていることが分かります。Functionを使って、カスタム認証を行う基礎的な実装を紹介してみました。パスコードによる復号・暗号化などの高度な仕組みについては触れていませんが、S3リソースの保護する方法の基礎的なやり方はご理解いただけたかと思います。CloudFront【AWS使い方ガイド】CloudFrontからOAI/OACを利用してアクセス制限付きのS3からリソースを取得する方法CloudFlontからS3の中のファイルリソースに、OAI/OACを使ってアクセスを制限させるような処理を設定してみます。記事の担当:taconocatナンデモ系エンジニア主にAngularでフロントエンド開発することが多いです。開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。プログラミングするのが好きな人間です。