Silverlightでのクロスドメインアクセス

Silverlightでクロスドメインアクセスするには「clientaccesspolicy.xml」か「crossdomain.xml」というファイル名のポリシーファイルを使うんだけど、てっきりこのファイルをSilverlightをホストするページと同じサイトに置いておけば、そこに書いてあるサイトにクロスドメインアクセスできるもんだと思ってたんだけど、全く違うみたいね。というかそんな事ができたらセキュリティもくそもないわなw・・・orz

そうじゃなくてSilverlightがアクセスするサイトに置いておいたら、そのサイトが許可するドメインのみがクロスドメインアクセスができるようになるという事だとやっと気付いた。

ようは「hoge.com」というドメインSilverlightページがはてなブックマークの情報を取ろうと思ったら、「http://b.hatena.ne.jp」にポリシーファイルを置いてもらって、「hoge.com」からのクロスドメインアクセスができるように許可してもらわないといけないわけ。

結局そういうことをしようと思うとサーバーサイド側でプロキシするしかないのね。

せっかくなのでポリシーファイルの例を載せておく。「hoge.com」というドメインSilverlightページがはてなブックマークAtomAPIに対してクロスドメインアクセスする場合に「http://b.hatena.ne.jp」に置いてもらう*1ポリシーファイルの例

clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
   <cross-domain-access>
       <policy>
           <allow-from>
               <domain uri="http://hoge.com"/>
           </allow-from>
           <grant-to>
               <resource path="/atom" include-subpaths="true" />
           </grant-to>
       </policy>
   </cross-domain-access>
</access-policy>

自分が作ったWebサイトのAPIをクロスドメインアクセスされてもいいという場合にポリシーファイルを作ってあげるということですな。その時は場所を限定しておいた方が得策。

ちなみにクロスドメインアクセスするための古典的な方法として動的なiframeの生成があるけど、これをSilverlightでやってみたらうまく動作しなかった。
iframeを生成してそこにページを読み込むところまでは正常に動作したけど、その読み込んだ内容へのアクセスはどうやってもできなかった。ブラウザ側なのかSilverlight側なのかわからないけど、危険な操作はブロックされるようになっているんだろう。

iframeを使った例
var iframe = HtmlPage.Document.CreateElement("iframe");
iframe.SetStyleAttribute("display", "none");
iframe.AttachEvent("onload", new EventHandler<HtmlEventArgs>((s, e) => {
   var contentDoc = (ScriptObject)e.Source.GetProperty("contentDocument");
   // ここから先は失敗する
   var body = (ScriptObject)contentDoc.GetProperty("body");
}));

HtmlPage.Document.Body.AppendChild(iframe);

*1:置いてもらえるわけがないけど