CloudFront 署名付き Cookie を使った会員制共通コンテンツのアクセス制御設定
目次
はじめに
ウェブサイトを運営する際、特定の会員にのみコンテンツを提供する場合がよくあります。提供されるコンテンツは主に以下の二種類に分けられます。
- 会員情報に紐づくコンテンツ: これには会員のマイページや、個別に登録されたお気に入りの一覧が含まれます。
- 会員に紐づかない共通コンテンツ: 会員向けの記事や動画ファイルなど、閲覧権限がある会員であれば誰もが同じ内容を見ることができるコンテンツです。
この中で共通コンテンツの場合、閲覧権限がある人であれば誰でも同じ内容を見ることが可能ですので、CDNキャッシュを活用することでオリジンサーバーの負荷を軽減できます。しかし、ただCDNのみを使用するだけだと、会員以外の人々もコンテンツにアクセス可能になってしまう可能性があります。
AWSが提供するAmazon CloudFrontでは、このような問題を解決するために、権限のある人だけがコンテンツにアクセスできるような仕組みがいくつか用意されています。本記事では、その中でも署名付きCookieを用いたアクセス制御の方法について説明します。
Amazon CloudFront と 署名付きCookie
署名付きCookieは認証トークンの一種です。CloudFrontに署名付きCookieの使用を設定している場合、リクエストに正しい署名付きCookieが含まれていないと、CloudFrontは403エラー(アクセス拒否)を返します。 キャッシュが含まれているときも同様の挙動となります。
署名付きCookieを発行するには以下の手順で作業を行います。
1) 署名に利用するキーペアを作成する
キーペア(秘密鍵・公開鍵のペア)を作成します。 キーペアは以下のコマンドで作成できます。
openssl genrsa -out private_key.pem 2048
openssl rsa -pubout -in private_key.pem -out public_key.pem
このコマンドで作成された private_key.pem が秘密鍵、public_key.pem が公開鍵です。
2) CloudFront のキーグループにキーペアを登録する
以下のURL内で説明されている「パブリックキーを CloudFront にアップロードするには」と「パブリックキーをキーグループに追加するには」を参考に、公開鍵をアップロードして、その公開鍵を利用するキーグループを作成します。 この時、登録した公開鍵に対してID (パブリックキーID) が発行されるので、こちらをメモしておきます。
3) CloudFront の Behavior でアクセス制限の設定を行う
CloudFront の Behavior から「ビューワーのアクセスを制限する」で Yes を選択して、Trusted Key groups の中から今回作成したキーグループを選択します。
アクセス制限は Behavior 単位で付与できるので、例えば /videos/*
以下にのみアクセス制限を付与することが可能です。
4) アプリケーションで署名付きCookieを発行する
AWSドキュメントの記載に従ってアクセスポリシーを作成した後、秘密鍵を用いて署名付きCookieを作成します。 署名付きCookieは CloudFront-Policy、CloudFront-Signature、CloudFront-Key-Pair-Id の3つ組で構成されており、これらをそれぞれ作成する必要があります。
複雑な内容となっていますので提供されているライブラリを使って生成するのが確実です。 PHP であれば AWS SDK for PHP の CloudFrontClilent#getSignedCookie が利用できます。
一方、Python のライブラリ (boto3) ではこの関数の提供がありませんので、ドキュメントの記載に従って自前で署名付きCookieを生成する必要があります。
これらの署名付き Cookie の発行はウェブサイトへのログイン時に行うと良いでしょう。 ただし、署名付き Cookie のポリシーとCookie そのものに有効期限が設定されていますので、ログインセッションに利用している Cookie と有効期限を同期させる必要がある点に注意が必要です。
署名付きCookieを利用する際の注意点
署名付きCookieのポリシーでは、1つのステートメントのみを含むことができます。これは、一組の署名付きCookieで複数のURLパスに対する設定を同時に行うことができないという意味です。例えば、/videos/*
と /images/*
を同一のポリシーに含めることはできません。これに対処するには、サイト全体をカバーするようなポリシーを設定するか、または /resources/videos/*
と /resources/images/*
のようにパスを共通化して /resources/*
と指定するなどの工夫が必要です。
署名付きCookieはCookieであるため、パスごとに個別に発行することも可能です。ただし、ブラウザのCookieの最大数には制限があるため、不必要に多くの署名付きCookieを発行することは避けるべきです。
より複雑なアクセス制御が求められるシナリオでは、署名付きCookieだけでは不十分な場合があります。例えば、会員が個別に購入したコンテンツへのアクセス制限を設定するような場合には、CloudFront FunctionsやLambda@Edgeを用いたアクセス制御が適しています。
おわりに
本稿では、CloudFrontを用いたアクセス制御における署名付きCookieの利用法と、その効果的なシナリオおよび限界について説明しました。CloudFrontは非常に柔軟なCDNであり、その多様な機能を活用することで、効率的かつシンプルに優れたインフラストラクチャを構築できる魅力があります。