Last time, we discussed how Silverlight applications talk to their site of origin server. In this post, we’ll dive into the high level concepts around Silverlight’s cross domain HTTP communication. Then next time, we’ll go into details of how to set up a cross domain policy file.
(I know - I lied! But part 2 was just getting too long… so I converted this to a 3 part series.)
What is Cross Domain Communication?
As mentioned last time, your Silverlight application by default can only talk back to its site of origin server. This is in line with the general browser sandbox, and is designed to prevent cross site forgery.
The site of origin server is determined by the app’s deployment URI: the location of the XAP for managed applications, the address of the XAML page for javascript applications.
If a HTTP request matches the origin server’s domain, protocol, and port number, then it’s considered a site of origin request and is allowed. Otherwise, it’s classified as a cross domain call.
Silverlight’s Cross Domain Policy Support
In order for a cross domain request to a particular web service to succeed, that web service needs to explicitly opt-in to 3rd party callers.
In Silverlight 2, the primary way of enabling cross domain calls is through a policy file placed at the root of the server. We support two types of policy files:
- Silverlight Cross Domain Policy File (clientaccesspolicy.xml)
- (A subset of the) Flash Cross Domain Policy File (crossdomain.xml)
What Can You Say to a Cross Domain Server?
Basic Capabilities
So, you’ve got permission from the appropriate policy file to make a cross domain request . What can you do with that request?
- Scheme: HTTP only (HTTPS support expected for V2 RTM)
- Verb support: GET & POST
- Request header support: Most standard & custom headers on POST only
- Status codes: 200 (OK) or 404 (NotFound) only
Also, all the requests you send will have have cookies and authentication sent with them. This is a significant point, and we’ll dig into it deeper in the part 3 of this post series.
The above capabilities are determined by the browser plugin’s networking APIs. Please see Part 1 for a deeper discussion of networking stack implementation.
Path Character Restrictions
Silverlight has placed certain restrictions on the path portion of a cross domain URI.
Specifically, a cross domain request path can ONLY contain:
- alpha numeric characters {a-z, A-Z, 0-9}
- ”,’ and "/’ and ‘~’
- "." but no consecutive ".."s
This restriction was done to prevent attacks around ".." and %-encoded ".."s, which malicious apps could use to try to escape out of an allowed path into a disallowed path. For Beta1, we decided to start by being extra conservative in the characters we allowed and then get feedback from you.
Does this character restriction prevent you from accomplishing your scenarios? We’ve heard not allowing ‘;’ is a big problem. Others? What support do you need?
Where does Silverlight Look for the Cross Domain Policy File?
When a request is detected as a cross domain request, we look first for a Silverlight policy file at the root of the request’s server.
| Request URI | Policy File Checked |
| http://foo.com/bar/data | http://foo.com/clientaccesspolicy.xml |
| http://sub.foo.com/bar/data | http://sub.foo.com/clientaccesspolicy.xml |
| http://foo.com:8080/bar/data | http://foo.com:8080/clientaccesspolicy.xml |
If such a clientaccesspolicy.xml file does not exist, we then look for a crossdomain.xml file at the same location.
Note: Certain servers do not return a 404 for a missing clientaccesspolicy.xml but a custom error page. Starting in Beta2, all malformed clientaccesspolicy.xml’s will trigger a fallback to the look for the crossdomain.xml
"Caching" Of Policy Files
Silverlight looks up the cross domain policy file for a particular server ONCE per application session. (Where an application session is the lifetime of a particular xap or xaml page instance in memory.)
Also, we use the browser networking stack to issue the request for the policy file, so the normal browser caching of the request happens under the covers.
Redirects
Redirects for the policy file itself are not allowed.
Request URIs redirects will only be successful if the original and final URIs are allowed via the appropriate cross domain policy. (Note: The browser handles handles the actual redirect logic itself and ensures it matches w3 spec.)
So that’s the high level cross domain behavior overview. Next time, we’ll drill into how to set up a cross domain policy file.
Do I understand correctly that the “.” (as in /over/there.xml) is illegal in a cross-domain URI?
Good clarification. Single dots are allowed (just not consecutive dots.) I clarified above.
That’s what I thought and denying consecutive dots is definitely good practice. Thanks for the clarification. URLs that do not have “file extensions” are cool anyway [grin].
Hmm, just curious is it in the future possible to load the policy-file from a different location? I’m thinking about using Google Picasa Web API.
http://code.google.com/apis/picasaweb/reference.html#Flash
They have a crossdomain.xml on a different location: http://photos.googleapis.com/data/crossdomain.xml
The best will be a clientaccesspolicy.xml file to be added by Google. But any ideas? There are a lot of Web APIs available but few maybe none have that clientaccesspolicy.xml file on the root.
My ISP is blocking port 80 so my website is using 8080. I just have my silverlight apps hosted there to show friends and family. Everything works great until i try to use my web service with silverlight.
As soon as i try to call any WebMethods async call externally it crashes. Everything works internally… Here is what i think is the problem. When i type [my ip]:8080 internally the domain is read as “localhost” externally its read as [my ip].
Externally this is a problem because i cannot host anything through just [my ip] it has to be through [my ip]:8080…
I am not sure this is what is happening, but i cannot figure it out.
Any ideas (other than getting on port 80)?
Can a path segment of a cross domain request contain parenthesis?
e.g.
http://myhost/base/accounts(A1094)?orderby=Name
I didn’t see the underscore or dash characters included, and they would need to be included in the allowed set.
Thanks,
Jeff