Policy file for NetTcp


As part of Silverlight 4, developers can now use the NetTcp framing protocol for their web services. This is an addition that we expect a lot of you will find useful. However, many of you will probably hit the dreaded CommunicationException that lurks the unsuspecting developer as soon as he tries to establish that first connection from their Silverlight client to the service.


You probably have seen this exception message before:


Could not connect to net.tcp://localhost:4502/MyService. The connection attempt lasted for a time span of 00:00:00.4270427. TCP error code 10013: An attempt was made to access a socket in a way forbidden by its access permissions.. This could be due to attempting to access a service in a cross-domain way while the service is not configured for cross-domain access. You may need to contact the owner of the service to expose a sockets cross-domain policy over HTTP and host the service in the allowed sockets port range 4502-4534.


This fairly long exception message comes to “there probably is not an adequate cross-domain policy for the service endpoint you are trying to access”. The Silverlight runtime requires all network communications to be authorized. This is done by retrieving a policy file to associate with a remote server before doing the actual communication. Hard core details about the mechanism can be obtained in the MSDN article entitled Network Security Access Restriction in Silverlight.


So how do you solve this fast and easy?


Short answer:


Create a file named clientaccesspolicy.xml with the file content described below and host it on an HTTP server at http://<<YourNetTcpIPAddress>>:80/clientaccesspolicy.xml.


Long answer:


For NetTcp connection, you must use a HTTP based socket policy.


If you already have HTTP web services in place, you simply will add a few lines to your clientaccesspolicy.xml file and you *should* be done. Otherwise, you need to create a file named clientaccesspolicy.xml that is served via HTTP at the base IP address of your service on the standard HTTP port 80.


Noticed I said base IP address here? Internally, the policy file is retrieved by the first IP address your domain name resolves to. So if your HTTP domain name does not resolve to the same IP address as your NetTcp service, you will need some workaround. One solution could be an adaptation of Carlos Figueira REST-based policy server.


The content of your clientaccesspolicy.xml for debugging can be the one shown here. This policy is very lax though, and as great as it is for debugging purpose, it will let any clients access your service in production. You should therefore tinker with it and adapt it to your specific needs before deployment.


<?xml version=1.0 encoding=utf-8?>


<access-policy>


  <cross-domain-access>


    <policy>


      <allow-from http-request-headers=*>


        <domain uri=* />


      </allow-from>


      <grant-to>


        <socket-resource port=4502-4534 protocol=tcp />


      </grant-to>


    </policy>


  </cross-domain-access>


</access-policy>


 


Once you have created your policy file and hosted it, test if it is retrievable by opening your browser and pointing it to http://<<YourNetTcpIPAddress>>:80/clientaccesspolicy.xml. Your browser should show you the content of your policy file. If this is the case, your Silverlight client should be free to talk with your NetTcp service!


-Christopher Scrosati
Developer, Silverlight WCF team

Comments (10)

  1. Kevin says:

    Life saver!

  2. this just does not work for me, says:

    Scenario –

    Simple WCF service hosted in a windows service at port 4502

    Web app at port 80 is a sharepoint foundation 2010 website, it has the Client access Policy XML & cross domain.xml at it root web directory, i have also placed it a inetpubwwwroot

    Here's my Client access Policy XML

    <?xml version="1.0" encoding="utf-8"?>

    <access-policy>

     <cross-domain-access>

       <policy>

         <allow-from http-request-headers="*">

           <domain uri="http://*"/&gt;

         </allow-from>

         <grant-to>

           <resource path="/" include-subpaths="true"/>

           <socket-resource port="4502" protocol="tcp" />

         </grant-to>

       </policy>

     </cross-domain-access>

    </access-policy>

    This is available as <IP address>/clientaccesspolicy.xml – i have tried it with browser,

    it showed in filddler once with 201 but then this request for clientaccesspolicy.xml is neer seen in fiddler trace also.

    But still keep on getting this error – WHAT IS WRONG ?

    TCP error code 10013: An attempt was made to access a socket in a way forbidden by its access permissions.. This could be due to attempting to access a service in a cross-domain way while the service is not configured for cross-domain access. You may need to contact the owner of the service to expose a sockets cross-domain policy over HTTP and host the service in the allowed sockets port range 4502-4534.

    Tried restarting service, Did IIS reset – the request doesnot show up again

  3. Ahobul says:

    I hosted wcf service in windows service then am not getting where to place these two(clientaccesspolicy.xml and crossdomainaccesspolicy) files.

  4. rubenhak says:

    Hi Yavor,

    First for all thank you for describing the problem and giving a solution. I've got the WCF service hosted under windows service, but luckily I've also got a IIS web site and just putting "clientaccesspolicy.xml" under web root does the trick. Now I can open the open silverlight from the web site and connect to remote server.

    Now i got different problem. If I open silverlight project in visual studio from remote computer and try to debug it i cannot connect to WCF service anymore. I get same cross-domain policy error message. One thing i noticed is that when I try to debug the Silverlight application it creates an HTML file under binDebug which has my Silverlight control in there and opens that in IE.

    Do you know how can i fix that? I really need to have ability to debug my Silverlight application that connects to WCF service.

    Thank you,

    Ruben

  5. Ashish G Madkaikar says:

    @this just does not work for me – My problem is exactly the same as your's .. here are some of my findings,I have not been able to use my nettcp wcf service with silverlight as i do with the asp.net client which runs just fine.

    Some important stuff about this whole thing

    1. Use fiddler and trace the clientaccesspolicy.xml request it would be like 127.0.0.1/clientaccesspolicy.xml. this request is made only once for a siliverlight app so once it fails you will have to change it and redeploy also clear %temp% make sure you get a 200 for clientaccesspolicy.xml request – you get this 200 you are done – forcing the runtime to make this request is important for the whole thing .

    2. Alternate Access mappings for Sharepoint web app for http://127.0.0.1 +

    3. Tell Sharepoint to exclude this resource its request processing

    <location path="clientaccesspolicy.xml">

       <system.web>

         <authorization>

           <allow users="*" />

         </authorization>

       </system.web>

     </location>

    4. i also had to turn on anonymous access for web app authentication to avoid the login popup (dont know th impact of this yet, but my focus is to make this silverlight 4 thing work with my sweet wcf service. )  

    after all this make sure port 80 i.e http://<serverip address> my case i used localhost –> added a host entry in host file for for 127.0.0.1 –

    this should turn your 404 to 304 (but still this is cached and silverlight wont take it build renmove the silverlight webpart from the page and put it again, modify the clientaccesspolicy.xml content save)

    make sure 127.0.0.1/clientaccesspolicy.xml is availaible…….

    Here i am stuck .. now the client times out.. cant doa a simple async connect to the service 🙁

    any pointers please let me know i am eager to hear and implement.

  6. dont forget this part... says:

    To use HTTP to retrieve the socket policy file, an application should set the SocketAsyncEventArgs.SocketClientAccessPolicyProtocol property to Http on the

    System.Net.Sockets.SocketAsyncEventArgs instance passed to the Socket.ConnectAsync method.

  7. This article is solved my problem. says:

    This article is solved my problem.

    Thanks a lot.

  8. Arsh says:

    Hi,

    You need to place the clientaccesspolicy.xml file in the root folder on the server. Also you might have to add an exception(in windows firewall on the server side) for the port which you are going to use.

    For more information:

    forums.silverlight.net/…/1

    Sample:

    iconnect.arshdeep-virdi.com/web

    Thanks,

    Arsh

  9. Gaurav says:

    Hi,

    I see the Connection Refused error as i try to establish the connection using socket. I am using http protocol with port number 4503 after added clientaccesspolicy.xml file, as suggested, on the server. I have client and server both on the same machine. Do you think that I am missing something.

    Please help me