Amazon CloudFront の署名付きURL(カスタムポリシー)を使って、ワイルドカードなコンテンツ配信をしてみた

# はじめに

[前回の記事](https://qiita.com/sugimount-a/items/53febd43e4cad7ffdb54)では、Amazon CloudFront の署名付きURL をカスタムポリシーで生成する方法を確認しました。今回はワイルドカードを使った、複数のオブジェクト配信を確認していきます。



前回の記事の内容では、カスタムポリシーをつかった署名付きURLの配信では、特定のオブジェクト `mycat.jpg` を指定した配信でした。 

```python
url = 'https://d31z1elfcc2o1s.cloudfront.net/mycat.jpg'
```



上記の方法でも問題はないのですが、複数のオブジェクトを配信したいときに、一つずつ署名付きURLを生成するのは、多少不便です。数が多い場合は、パフォーマンスへの影響も気になります。そこで、カスタムポリシーを使った署名付きURLでは、ワイルドカードを使った複数のオブジェクトが可能です。

次のような指定をした署名付き URL を生成したとき、

```python
url = 'https://d31z1elfcc2o1s.cloudfront.net/mycat*.jpg'
```



複数のオブジェクトの配信で使いまわせるようになります

```
mycat1.jpg
mycat2.jpg
mycat3.jpg
mycat4.jpg
...
```



それではやっていきましょう。



# S3 にオブジェクトを配置

S3 に `mycat1.jpg` と `mycat2.jpg` を配置しました。

![image-20220226123905825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/edf84a7f-d2c1-fab5-5bdc-68124df90d9e.png)



# 署名付きURL をワイルドカードで生成

[前回の記事](https://qiita.com/sugimount-a/items/53febd43e4cad7ffdb54)の環境をそのままつかっていきます。もし、環境が無い場合は[前回の記事](https://qiita.com/sugimount-a/items/53febd43e4cad7ffdb54)を参照してください。

Python のソースコードはこんな感じです。

```python
import datetime

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from botocore.signers import CloudFrontSigner
from dateutil import tz


def rsa_signer(message):
    with open('/home/ec2-user/temp/cloudfront-presign/private_key.pem', 'rb') as key_file:
        private_key = serialization.load_pem_private_key(
            key_file.read(),
            password=None,
            backend=default_backend()
        )
    return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())


key_id = 'K1DYHGI8XWLXZL'
url = 'https://d31z1elfcc2o1s.cloudfront.net/mycat*.jpg'
expire_date = datetime.datetime(
    2022, 2, 26, 22, 10, 0, 0, tz.gettz('Asia/Tokyo'))

cloudfront_signer = CloudFrontSigner(key_id, rsa_signer)

# Create a signed url that will be valid until the specific expiry date
# provided using a canned policy.
policy = cloudfront_signer.build_policy(
    url, expire_date, date_greater_than=None, ip_address='0.0.0.0/0')

signed_url = cloudfront_signer.generate_presigned_url(
    url, date_less_than=None, policy=policy)
print(signed_url)
```



Python プログラムを実行すると、署名付き URL が標準出力に表示されます。

```
> python cloudfront-create-presign.py
https://d31z1elfcc2o1s.cloudfront.net/mycat*.jpg?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kMzF6MWVsZmNjMm8xcy5jbG91ZGZyb250Lm5ldC9teWNhdCouanBnIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjQ1ODgxMDAwfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjAuMC4wLjAvMCJ9fX1dfQ__&Signature=mKwK-TlJOFXVB4ptnIUUxyuACXVuSjuLy4B8BU5MwAs6JkxNYOHl0VlIUj6YrTt4Ng7TvoTbT638U6amWlAP2MGOs~0MMYpuHjvqX-T0vcuKXmcbVuWhq8EemNe1veAD2THrHTyXMRCVvjVdvw1SxGzleZgE35hP0d61GwU69Tcr0qLW6bipzmgd3-rRTDT2dVKlgPNCYATsWIpR01lYj2D5SUfdEtW9inCD2f4sWafULLT7FhMRq724OArOjVwe9LdZbxPP4Go6W5h9hcwxg-qV3wLjejiql6HjBqL54ve2fRcRb41W6-czjqS6-N8ztgppO6BH8MK~--5O9OmuLg__&Key-Pair-Id=K1DYHGI8XWLX1ZL
```



# アクセス確認

生成した署名付き URL は、`mycat*.jpg` というアクセスパスになっています。これを、S3 にアップロードしたファイル名 `mycat1.jpg` に書き換える必要があります。

```
https://d31z1elfcc2o1s.cloudfront.net/mycat1.jpg?Policy=hogehoge
```



これでアクセスを行うと、無事に家猫の画像が表示されました！かわいい。

![image-20220226124147331.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/9124ee21-0d3b-6b49-7b8b-c5599744bb34.png)



ワイルドカードで生成している署名付きURLなので、同様に `mycat2.jpg` に書き換えてアクセスしてみましょう。

```
https://d31z1elfcc2o1s.cloudfront.net/mycat2.jpg?Policy=hogehoge
```



こでも想定どおり、画像が表示されました！キリっとしていてこれもかわいいですね。

![image-20220226124215374.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0d8c728a-3101-39f7-b441-c90931114a80.png)



# まとめ

署名付きURL(カスタムポリシー)をつかって、ワイルドカードの生成方法を確認しました。複数のオブジェクトをまとめて配信したいときに、簡便に生成する方法として便利ということがわかりました。