S3のCORS設定方法を確認してみた ~複数ドメインからのHLS動画再生を許可するケース~

複数のドメインからのクロスドメインアクセスを許可する場合、他条件が同じであればAllowedOrigin要素を増やします。またサブドメイン部分にワイルドカード*が使用できますが、Zone Apexは含まれないので別途指定が必要になります。
2020.03.31

はじめに

清水です。先日、以下のエントリでS3でHLSファイルをホスティング、別ドメインでホスティングしているVideo.jsからHLS再生する場合に、S3でCORS設定が必要である、ということを確認しました。

今回も上記のケースと同様、HLSファイルをS3でホスティング場合ですが、複数のドメインからVideo.jsによるHLS再生を許可するという場合に、具体的にどのようなS3のCORS設定を行えばよいかを確認してみたのでまとめてみたいと思います。具体的には、以下2点を確認してみました。

  • ドメインを複数(2個以上)にする場合のCORS設定の記載方法
  • ワイルドカード*をサブドメインに使う場合のZone Apexの扱い

基本となる単一ドメインからの再生を許可するCORS設定

まずは基本となる、単一ドメインからのアクセスを許可するCORS設定を確認します。AllowedOrigin要素に該当ドメインを記載して、以下のようになりますね。なお、AllowedOrigin以外の要素については、MediaStoreのCORSポリシー例を参考にしています。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www1.example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

こちらの例は、以前のエントリで別ドメインでホストしているVideo.jsから動画再生ができることを確認しています。以降このCORS設定をベースに、複数ドメインからのクロスドメインアクセスを許可する設定を確認していきたいと思います。

なお、検証のためMaxAgeSecondsの値は1として確認しています。(本エントリ中のでは3000として記載しています。 *1)また、複数のドメイン(サブドメイン)が出てきますが、一式のELB-EC2にRoute 53で複数のドメインを割り当てている、という状況で確認を行いました。

ドメインを複数にする場合のCORS設定の記載方法

続いて、複数(2個以上)のドメインからのクロスドメインアクセスを許可したい場合のCORS設定記載方法について確認します。

AllowedOrigin要素を増やす

CORSRule内、AllowedMethod要素について注目すると、2つ列挙されていますね。これにならい、AllowedOrigin要素を2つにしてみましょう。以下の設定をS3バケットに行ってみます。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www1.example.net</AllowedOrigin>
    <AllowedOrigin>https://www2.example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>1</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
v</CORSRule>
</CORSConfiguration>

再生ページを各ドメインの直下、videojs.htmlのページで準備しています。https://www1.example.net/videojs.htmlhttps://www2.example.net/videojs.htmlとも、再生ができました!

当然、許可されていないドメインでは再生ができません。今回はhttps://www3.example.net/videojs.htmlで確認しました。このwww3のドメインについてもCORS設定で同様に設定すれば再生可能になります。

またAllowedOriginにはhttpsで指定しています。このままだとhttpではアクセスができない、ということは以前のエントリでも確認したとおりです。httpでもクロスドメインのアクセスを許可したい場合、AllowedOrigin要素としてhttpについても記載しましょう。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www1.example.net</AllowedOrigin>
    <AllowedOrigin>https://www2.example.net</AllowedOrigin>
    <AllowedOrigin>http://www1.example.net</AllowedOrigin>
    <AllowedOrigin>http://www2.example.net</AllowedOrigin>            
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

またクロスドメインと言っていますが、IPアドレスでも指定が可能でした。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www1.example.net</AllowedOrigin>
    <AllowedOrigin>https://www2.example.net</AllowedOrigin>
    <AllowedOrigin>http://203.0.113.31</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

CORSrule要素を増やす

もう一つの方法として、CORSRule要素を複数とすることができます。具体的には以下のようなCORS設定です。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www1.example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>https://www2.example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

こちらでも、複数ドメインによるクロスドメインアクセス許可が可能です。AllowOrigin要素を複数とした場合とと比較すると、AllowedMethodMaxAgeSecondsAllowedHeaderなど各要素をドメインごとに指定できる、という点がことなるかと考えます。これらの要素の値がドメインごとに同一であれば、冗長になってしまう、とも言えますね。

ワイルドカード*をCORSのドメイン指定に使う場合の注意点

複数のドメインからのクロスドメインアクセス許可を行う場合、条件によってはワイルドカード*で一括して指定してしまう、ということ考えられると思います。S3のCORS設定でもこのワイルドカード*が使えます。具体的には以下のような記載ですね。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://*.example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

さてこの場合、example.netの扱いについてはどうなるでしょうか……。結論としては*.example.netexample.netは含まれません。個別に指定する必要があるので注意しましょう。

以下のように、example.net*.example.netそれぞれを記載する必要があります。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://*.example.net</AllowedOrigin>
    <AllowedOrigin>https://example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

まとめ

HLSファイルをS3でホスティングし、複数のドメインでホスティングされているVideo.jsからHLS再生を許可するためのCORS設定について確認してみました。

以下が本エントリで確認したことをまとめたCORSポリシーかなと思います。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://example.net</AllowedOrigin>
    <AllowedOrigin>https://*.example.net</AllowedOrigin>
    <AllowedOrigin>http://example.net</AllowedOrigin>
    <AllowedOrigin>http://*.example.net</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
  • 複数ドメインからクロスドメインアクセス許可をする場合、他条件が同じであればAllowedOrigin要素を増やす
  • サブドメイン部分にワイルドカード*が使用できるが、Zone Apexは含まれないので別途指定が必要

脚注

  1. のちのち、私がコピペしやすくするためですね。