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 https://<<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 https://<<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
Anonymous
March 01, 2011
Life saver!Anonymous
March 29, 2011
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://"/> </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 againAnonymous
April 19, 2011
I hosted wcf service in windows service then am not getting where to place these two(clientaccesspolicy.xml and crossdomainaccesspolicy) files.Anonymous
May 02, 2011
@Ahobul - check out blogs.msdn.com/.../10042269.aspxAnonymous
June 02, 2011
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, RubenAnonymous
June 03, 2011
The comment has been removedAnonymous
August 21, 2011
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.Anonymous
October 23, 2011
This article is solved my problem. Thanks a lot.Anonymous
June 22, 2012
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, ArshAnonymous
March 01, 2013
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