ASP.NET Webサービスを呼び出す際の注意点
ここまででSilverlightからWebサービスを呼び出すことが可能になりました。
SilverlightからWebサービスを呼び出す際にはいくつかの注意点がありますので、ここで触れておきましょう。
WebServiceの設定情報
サンプルではVisual Studioのテスト用Webサーバー上にWebサービスを配置しましたが、Silverlightを本番環境に移送する場合は、Webサービスの参照も本番のWebサービスに切り替える必要があります。
WindowsアプリケーションやASP.NETではapp.configやweb.configといった設定ファイルにWebサービスへの参照情報を記述しましたが、Silverlightでもサービスリファレンスの設定時に作成されるServiceReference.ClientConfigファイルにWebサービスへの参照情報が記述されています。
本番環境に移送する場合には、このファイルのendpoint情報を変更しSilverlightを再パッケージ(XAP)化する必要があります。このため実際の開発時にはテスト用と本番用の2つのServiceReference.ClientConfigを用意したり、MSBuildのビルド時に定義を置き換えたりといった工夫が必要になると思います。
MSBuildのビルド時にXMLの定義情報を書き換える方法がNAndu氏の記事『XmlMassUpdateタスクを使用したデプロイ』にまとまっています。ぜひ参考にしてください。
クロスドメインリクエスト
もう一つ大きな問題になるのが、Silverlightから違うドメインのサービスを呼び出す際に問題になるクロスドメインリクエストの問題です。
Silverlightの既定ではSilverlightをホストしているドメインにあるサービス以外へのリクエストは禁止されています。もしSilverlightからの接続が許可されていない他ドメインにあるWebサービスを呼び出そうとした場合、実行時にCommunicationExceptionの例外が発生します。
他ドメインに対するリクエストを無制限に許してしまうと、悪意を持ったプログラムは、利用者が気づかないうちに他ドメインのサービスに対し、サービス拒否攻撃(DDoS)やDNS Rebinding、逆トンネルといった攻撃を行ってしまう可能性があります。
Silverlightでは、Webサービスをホストするドメインのサーバーで、Silverlightからのリクエストを許可することを表すドメイン間ポリシーファイルをサーバーのルートサイトに公開してもらうことで、クロスドメイン間のリクエストが許可される設計になっています。
つまり業務で他システムのサービスを利用する場合、対象サービスのルートサイトにドメイン間ポリシーファイルが提供されているか、提供してもらうことが可能かを確認・検討することが必要となります。
また、Visual StudioのテストWebサーバーでSilverlightをホストしている場合、「http://localhost:2591」といったようにポートが自動的に割り振られます。この状態で、「http://localhost」に存在するWebサービスに対してリクエストを発行すると、上記のCommunicationExceptionが発生してしまいます。
この場合、localhostのルートサイト(既定ではC:\Inetpub\wwwroot)に後述するドメイン間ポリシーファイルを配置する必要があります。
Visual StudioのテストWebサーバーがバインドするポート番号は次の方法で確認・設定を行うことができます。Visual Studioのソリューションエクスプローラから、該当Webサイトプロジェクトを右クリックして、[プロパティ]-[Web(ポート番号の確認)]を開いてください。
ドメイン間ポリシーファイル
Silverlightで使用されるドメイン間ポリシーファイルは、Flashで使用されているcrossdomain.xmlとSilverlightで新たに採用されたclientaccesspolicy.xmlの2種類があります(Silverlightではcrossdomain.xmlはすべてのドメインに対しアクセスを許可する/しないの2択しか設定できません)。
Silverlightではクロスドメインへのリクエストがあった場合、まず始めに対象ホストのルートサイトからclientaccesspolicy.xmlを検索します。clientaccesspolicy.xmlが存在しない場合は続いてcrossdomain.xmlを検索し、発見されたドメイン間ポリシーファイルを元にアクセス制御を行います。読み込まれたドメイン間ポリシーファイルの設定はブラウザセッションの間有効になります。テスト中にドメイン間ポリシーファイルを書き換えても、ブラウザを再起動するまで変更が有効になりませんので注意してください。[リスト3]にclientaccesspolicy.xmlの例を示します。
<?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy > <allow-from http-request-headers="SOAPAction"> <domain uri="http://localhost:2591"/> </allow-from> <grant-to> <resource path="/webservice1/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
この例では、「http://localhost:2591」ドメインからのSOAPActionについて、webservice1ディレクトリにあるWebサービスについてアクセスが許可されています。
また、例えばすべてのドメインから、すべての要求に応えるためには[リスト4]のように構成を変更します。
<?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy > <allow-from http-request-headers="*"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
clientaccesspolicy.xmlを配置して動作を確かめてください。問題なくサービスを呼び出すことはできましたか?