Flash Player 10.1 と AIR 2 から、セキュリティ関連の新しい機能が追加されました。他のドメインから読み込むファイルの種類を制限できる機能です。
セキュリティドメイン
新機能の前に、セキュリティドメインについて確認です。
セキュリティドメインは、Flash Player に読み込んだ SWF ファイルを管理するための機能です。同じセキュリティドメイン内のリソースには自由にアクセスできますが、他のセキュリティドメイン内のリソースには (通常) 勝手にアクセスできないようになっています。
基本的には、SWF ファイルの置かれているサーバーのドメインごとに、セキュリティドメインが作られます。例えば、最初に読み込まれた SWF ファイルと、その SWF ファイルが読み込んだ SWF ファイルが、それぞれ別のサーバーから読み込まれた場合、2 つのセキュリティドメインがつくられます。そして、2 つの SWF ファイルは、それぞれ対応するセキュリティドメイン内に置かれます。
"基本的に" と書いたのは、外部ドメインのファイルを、ファイルを要求した SWF のセキュリティドメインに読み込む手段があるからです。以下の 2 つの API が提供されています。
1 つ目は、LoaderContext.securityDomain 属性に、読み込む側のセキュリティドメインである SecurityDomain.currentDomain を設定してから Loader.load() メソッドを呼ぶ、というものです。これで、外部ドメインのファイルでも、load() を呼んだ SWF と同じセキュリティドメインに読み込まれます。下はそのサンプルです。
var ld:Loader = new Loader(); var lc:LoaderContext = new LoaderContext(); // 読み込む側のセキュリティドメインを指定 lc.securityDomain = SecurityDomain.currentDomain; // 第2引数にLoaderContextを指定 ld.load(new URLRequest("http://not.my.domain.jp/foo.swf"), lc);
2 つ目は、Loader.loadBytes() メソッドを、2 つ目の引数にドメインを明示的に指定しない状態で呼ぶという方法です。Loader.loadBytes() は、デフォルトで loadBytes() を実行した SWF と同じセキュリティドメインにデータを読み込みます。
なお、外部ドメインのファイルを読み込むには、外部ドメイン側のサーバー上に、「load() を実行した SWF のドメインを信用する」 という内容のポリシーファイルが置かれていることが前提になります。
ちなみに、他のドメインのファイルを自セキュリティドメインに読み込む事は、ファイルを他のサーバーから自分のサーバーにコピーした後にダウンロードするのと実質的に同じです。
AIR のアプリケーションでは、securityDomain を指定する事ができません。そのため、外部ドメインのコンテンツを自セキュリティドメインに読み込む事はできません。
LoaderContext.allowCodeImport
それでは、本題の新機能について。外部ドメインから自セキュリティドメインに読み込めるファイルの種類を指定できる、という機能です。
上で触れたように、AS 3 では、2 つの API (load と loadBytes) が、他のドメインから自セキュリティドメインへの読み込みを指定できるようになっています。これらの API は、どちらも SWF ファイルと、イメージファイル (JPEG, PNG, GIF) の読み込みに利用できます。(ポリシーファイルが正しく設定されていれば)
これも上で触れたように、AS 3 からコンテンツを自由に操作するには、同じセキュリティドメインにそのコンテンツを読み込む必要があります。画像データのピクセル値を取得するとか、動的に加工するとかいう場合は、画像データと処理を行う SWF が同じドメインになければなりません。
イメージデータは実行できるコードを持たないので、自ドメインに読み込む事にあまり抵抗は無いかもしれませんが、外部の SWF を読み込むのはちょっと怖い、かも。。。と思った人のために、イメージファイルだけクロスドメインの読み込みを許可、という指定ができるようになりました。
ということで、Flash Player 10.1 と AIR 2 からは、LoaderContext.allowCodeImport = false と指定すると、SWF ファイルの他ドメインから自ドメインへの読み込みは実行されなくなります。
下は loadBytes() を使った簡単な例です。
var ld : Loader = new Loader(); ld.contentLoaderInfo.addEventListener("complete", onLoadComplete); ld.contentLoaderInfo.addEventListener("securityError", onSecurityError); var lc : LoaderContext = new LoaderContext(); // SWFを自ドメインに読み込まないよう設定 lc.allowCodeImport = false; // 第2引数にLoaderContextを指定 ld.loadBytes(myByteArray, lc);
このサンプルを実行すると、読み込んだコンテンツが外部ドメインの SWF ファイルだった場合は、セキュリティエラーが発生し、onSecurityError が呼ばれます。
LoaderContext.allowCodeImport の設定は、外部ドメインからの読み込みのみに影響します。自ドメインからであれば、LoaderContext.allowCodeImport = false の状態でも SWF を普通に読み込めます。
AIR には同様の属性が既に存在していました。LoaderContext.allowLoadBytesCodeExecution です。AIR アプリでは LoaderContext.securityDomain が使えないため、この属性は loadBytes() メソッド専用でした。そのため、名前もそれらしくなっています。
今後は、AIR アプリでも LoaderContext.allowCodeImport の使用が推奨されています。Flash Player とコードを書き分ける必要がないので、というのが理由だそうです。
コメントする