Carlos' blog

Debugging tips and small examples for WCF

Enabling cross-domain calls for Silverlight apps on self-hosted web services

In order for a Silverlight (or Flash) app coming from one domain to be able to consume data from services in a different domain, the service must "allow" the app to do so by providing a policy file which grants access (to prevent all sorts of cross-site scripting attacks). This policy file must be located in the root of the "domain" (hostname + port), so if your service is located at http://my.service.com:8000/Service/CoolService.svc/Endpoint, the policy file must be located at http://my.service.com:8000/ClientAccessPolicy.xml (or http://my.service.com:8000/crossdomain.xml in case of the Flash format). That's fairly easy to do on a IIS-hosted service (simply put the static policy file in the root of the web), but for self-hosted apps it isn't as simple (there's no "root" of the web).

To solve this problem for self-hosted WCF services, you can use the web programming model support fairly easily. Basically, you'd define the base address at the root of the domain, and have a web endpoint at the "" address. All the "real" service endpoints would then be in different addresses. The example below shows it in action:

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 Test()
    {
        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.Write("Press ENTER to close");
        Console.ReadLine();
        host.Close();
    }
}

 

Published Friday, March 07, 2008 5:51 PM by carlosfigueira
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Silverlight Web Services Team said:

One interesting question from the WCF forums: how to enable the cross-domain calls to self-hosted services,

March 7, 2008 1:34 PM
 

Community Blogs said:

Karen Corby provides us 3 SL2 controls, Carlos Figueira details the cross-domain policy file, Jesse Liberty

March 15, 2008 3:45 PM
 

Pierre Lagarde, Blog said:

Depuis la mise a disponibilité de Silverlight 2 au Mix08 il y a eu beaucoup d'articles, de blogs sur

March 18, 2008 3:19 AM
 

Silverlight Web Services Team said:

Silverlight 2 Beta1 makes it easy to use Web Services based on either the WCF technology (Windows Communication

April 16, 2008 2:40 PM
 

A Cup of Silverlight, RIA & Interoperability said:

This tip concerns those who wants to use self hosting capabilities of services in WCF or Restlet in cross-domain

August 11, 2008 8:24 AM
 

Shahar Ron said:

Recently I tried to call a WCF service hosted in a windows service from silverlight. I got an HTTP 404

October 25, 2008 11:15 AM
 

ShaharRon said:

See a small correction needed to your clientaccesspolicy.xml

October 27, 2008 9:04 AM
 

ShaharRon said:

October 27, 2008 9:05 AM
 

Zuker On Foundations said:

Read the full details Here . Carlos came up with an elegant way to enable cross domain calls from silverlight

December 8, 2008 12:57 AM
 

Zuker On Foundations said:

Read the full details Here . Carlos came up with an elegant way to enable cross domain calls from silverlight

January 15, 2009 9:03 AM
 

Masande said:

Hi Carlos I was able to implement and run the sample code you posted successfuly but get the error

"This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details" when running that very same code in the Web Service Software Factory. Please assist

March 6, 2009 3:53 AM
 

xmhai said:

Hi, Carlos,

It only works fine for the first 5 requests, i.e. click the "refresh" button in IE. After that, "The remote server returned an error: NotFound" exception will raise for subsequent requests. Then I have to shutdown the Service. Do you have any idea? it looks like buffer overflown.

March 17, 2009 12:12 AM
 

Israel Aece said:

ClientAccessPolicy.xml sem IIS

May 15, 2009 10:50 AM
 

mdmSoftware said:

This works great for me provided the WCF service is up and running on my local box prior to launching my Silverlight application.  I have a self hosted WCF Windows service and I am hitting it from a Silverlight page using the localhost cross domain access trick above.  If I do not launch my WCF service until after hitting my Silverlight page but rather launch it after, my Silverlight application can never recover.  Looks like the clientaccess and crossdomain negotiation for the host domain are done somewhere behind the scenes in the client factory and I can't seem to find a way to re-initiate the check for security access.  What am I missing?

July 31, 2009 9:09 AM

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit

About carlosfigueira

Software Design Engineer in Test at the Connected Frameworks team at Microsoft.

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker