(1 item) |
|
(1 item) |
|
(5 items) |
|
(1 item) |
|
(1 item) |
|
(2 items) |
|
(2 items) |
|
(4 items) |
|
(1 item) |
|
(6 items) |
|
(2 items) |
|
(4 items) |
|
(1 item) |
|
(4 items) |
|
(2 items) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(2 items) |
|
(2 items) |
|
(5 items) |
|
(3 items) |
|
(1 item) |
|
(1 item) |
|
(1 item) |
|
(3 items) |
|
(1 item) |
|
(1 item) |
|
(2 items) |
|
(8 items) |
|
(2 items) |
|
(7 items) |
|
(2 items) |
|
(2 items) |
|
(1 item) |
|
(2 items) |
|
(1 item) |
|
(2 items) |
|
(4 items) |
|
(1 item) |
|
(5 items) |
|
(1 item) |
|
(3 items) |
|
(2 items) |
|
(2 items) |
|
(8 items) |
|
(7 items) |
|
(3 items) |
|
(7 items) |
|
(6 items) |
|
(1 item) |
|
(2 items) |
|
(5 items) |
|
(5 items) |
|
(7 items) |
|
(3 items) |
|
(7 items) |
|
(16 items) |
|
(10 items) |
|
(27 items) |
|
(15 items) |
|
(15 items) |
|
(13 items) |
|
(16 items) |
|
(15 items) |
I recently ran into what appears to be a bug in Silverlight 2 Beta 1’s handling of cross-domain web service access when using a clientaccesspolicy.xml file. I’m hoping this post might save a few other people the time it took me to work out what was going on here.
Here’s the executive summary: if the web service exposes resources whose URIs contain semicolons, you will not be able to access those resources cross-domain if you’re using clientaccesspolicy.xml. The workaround is to use crossdomain.xml instead.
Now for the more detailed version.
In case you’re not familiar with cross-domain web service access, here’s the basic idea. By default, a web browser won’t let client-side code go connecting to any old web site. Client-side code is allowed to make requests against the web site from which it was originally downloaded, and it should only have access to other sites if those sites opt in.
In pure AJAX sites, this is often achieved using a faintly smelly hack where web services return runnable script rather than simple data. Flash introduced a somewhat more formal mechanism by which a web site can declare that it’s happy to be accessed by client-side code from other domains. Silverlight now supports this feature as of v2 beta 1.
Here’s an example. If your web site offers a resource called /crossdomain.xml containing this:
<!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>
the site is declaring that it is open to anyone.
This policy is enforced on the client side by whatever runtime is performing the cross-domain network activity. Both Flash and Silverlight 2 beta 1 will look for this file when code in these runtimes attempts to access a web site from another domain. (This doesn’t help you from JavaScript, because today, no browser script engine supports this mechanism.)
One problem with this is that it’s a bit of a blunt instrument. You can be selective about who is allowed to access your site – you don’t have to use a wildcard. But you can’t be selective about what they can access. E.g., I might like to say that only content beneath a particular URI should be accessible to client code that originated from external domains.
As well as supporting Flash’s mechanism, Silverlight 2 beta 1 also introduces a more selective form of cross-domain policy. Before looking for a Flash-style crossdomain.xml resource, Silverlight will look for a clientaccesspolicy.xml file. This has a slightly more complex structure that enables you to constrain what a client can do. Here’s an example:
<access-policy> <cross-domain-access> <policy> <allow-from> <domain uri="*"/> </allow-from> <grant-to> <resource path="/extsvc/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
This says that clients from any external domain are granted cross-domain access, but it limits it to resources that start with /extsvc/.
This is a little more flexible than the Flash approach – it lets you make only selected parts of your site available. With crossdomain.xml, you would need to expose services under a distinct domain name to get this selectivity. Obviously that’s not rocket science – it’s certainly possible to present various services under various different domain names. So Silverlight’s approach doesn’t exactly enable anything that was impossible under Flash. On the other hand, this is a whole lot more convenient for people whose web hosting arrangements might not make it so easy to crank up new domain names for each set of services requiring distinct client access policies. And editing a text file is usually a more lightweight process than partitioning a web site’s services across multiple domains.
Unfortunately, there seems to be a problem in beta 1 of Silverlight. If the service you wish to access has a semicolon in its URI, Silverlight won’t allow your client-side code to access it, no matter what the clientaccesspolicy.xml file says. This is unfortunate if you’re using a service written the way advocated in RESTful Web Services, which recommends delimiting order-independent parts of a URL with semicolons. And the service I was using did exactly that. It took me a while to work out that it was specifically the semicolons that were causing problems, hence this post.
This is presumably just a bug in the code that works out whether any particular URI is permitted by the policy. Since the simpler crossdomain.xml grants all-or-nothing access, it never has to examine the URI, so it doesn’t have this problem. That’s why the simpler but less flexible crossdomain.xml offers a workaround here.
If you want to learn more about Silverlight, I’ll be teaching the Silverlight course that Fritz Onion and I co-author for Pluralsight in London in a couple of weeks. The 4 day course will be running at Old Street from 31st March to 3rd April. (And I’ll be teaching our WPF course at the same location the following week.)