WCF自托管模式下的SilverLight跨域访问

WCF自托管模式下的SilverLight跨域访问

在WCF为SilverLight提供服务的应用场景中,跨域访问带来的问题会给很多初学者不少困难。

问题的本质:一个Silverlight(或Flash)客户端来自某一个域,为了能够获取来自不同域服务的数据,服务必须提供了策略文件,该文件授予访问(防止各种跨站点脚本攻击)。而这个策略文件必须位于根的“域”(主机名+端口),所以如果你的服务在http://my.service.com:8000/Service/CoolService.svc/Endpoint

那么策略文件必须位于在

http://my.service.com:8000/ClientAccessPolicy.xml(或http://my.service.com:8000/crossdomain.xml Flash格式情况

IIS托管服务的应用场景中这是容易做到简单地把静态策略文件网站的根自托管应用程序不是那么简单没有“网页

为了解决这个问题,在WCF自托管模式中可以使用Web编程模型的支持事实上,你需要域的根基址定义有一个提供获取ClientAccessPolicy.xml策略文件网络端点。而所有的“真实服务端点在不同的网络端点。下面的例子显示具体实现

 public class SelfHostedServiceWithSilverlightPolicy
 {
       [ServiceContract]
       public interface ITest
       {
           [OperationContract]
           string Echo(string text);
       }
[ServiceContract]
public interface IPolicyRetriever { [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")] Stream GetSilverlightPolicy(); [OperationContract, WebGet(UriTemplate = "/crossdomain.xml")] Stream GetFlashPolicy(); }
public class Service : ITest, IPolicyRetriever { public string Echo(string text) { return text; } Stream StringToStream(string result) { WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; return new MemoryStream(Encoding.UTF8.GetBytes(result)); } public Stream GetSilverlightPolicy() { string result = @"<?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>"; return StringToStream(result); } public Stream GetFlashPolicy() { string result = @"<?xml version=""1.0""?> <!DOCTYPE cross-domain-policy SYSTEM ""http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd""> <cross-domain-policy> <allow-access-from domain=""*"" /> </cross-domain-policy>"; return StringToStream(result); } }
public static void Main() { string baseAddress = "http://" + Environment.MachineName + ":8000"; ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic"); host.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; host.Description.Behaviors.Add(smb); host.Open(); Console.WriteLine("Host opened"); Console.WriteLine("Press ENTER to close"); Console.ReadLine(); host.Close(); } }

 工具支持

事实上,WCF的开发离不开网络嗅探工具的支持(推荐Fiddler)。在出现问题的时候我们可以使用它来定位问题点。

使用Fiddler,我们可以发现在Silverlight第一次使用服务前会先访问对于路径下的ClientAccessPolicy.xml策略文件。

参考文献http://blogs.msdn.com/b/carlosfigueira/

posted on 2012-05-04 11:03  憨熊之家  阅读(407)  评论(2编辑  收藏  举报

导航