Question

I have two servers. Server A is an internal server that has access from the outside world set up here in my office. It has a Rails server running on it. I have a second server, Server B, that contains all our static content (images, swfs, javascript, css, etc.), it is an Amazon S3 server. I have given all these files public access.

What I am attempting is to put a swf from Server B on a page served by Server A. Then, the other assets that the swf requires in order to display get dynamically loaded from Server B. Unfortunately, however, somewhere along the way it's failing and the files that are requested to be dynamically loaded just never arrive.

Based on errors in my browser console the swf is expecting a crossdomain.xml file to be on Server A. Based on this, it also needs one to be on my S3 server. So, that being the case I have created two crossdomain.xml files, one for each server.

This is Server A's crossdomain.xml file:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE cross-domain-policy SYSTEM
  "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-access-from domain="s3-bucket-name.s3.amazonaws.com" />
</cross-domain-policy>

This is Server B's crossdomain.xml file:

<?xml version="1.0" encoding="UTF-8"?>    
<!DOCTYPE cross-domain-policy SYSTEM
  "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <site-control permitted-cross-domain-policies="master-only"/>
  <allow-access-from domain="*.server-a.com"/>
  <allow-http-request-headers-from domain="*.server-a.com" headers="SOAPAction"/>
</cross-domain-policy>

Additionally, I am explicitly loading Server B's crossdomain.xml file in my swf:

Security.loadPolicyFile("https://s3-bucket-name.s3.amazonaws.com/crossdomain.xml");

No matter what I do, however, it just does not work. I'm not sure what else to try. I've tried looking through a number of the solutions here on SO but nothing has helped me resolve my problem yet. Surely someone else has had more experience in this than I have and can give me some guidance, I'm pretty much out of ideas at this point.

Update Updating my question with some more info.

I tried setting both policy files to * and it started working until it hit:

SecurityError: Error #2121: Security sandbox violation: Loader.content: s3.amazonaws.com/bucket_name/swfs/foo.swf cannot access s3.amazonaws.com/bucket_name/data/swfs/bar.swf. This may be worked around by calling Security.allowDomain.

Additionally, I ran Charles and it is pulling the crossdomain.xml from both my local server but I don't see it for s3.

Update 2 I tried adding this to the loader:

var context:LoaderContext = new LoaderContext();
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = ApplicationDomain.currentDomain;
Loader.load(new URLRequest(_dataFile), context);

This resulted in the files actually downloading! Unfortunately now it crashes out with this:

SecurityError: Error #2119: Security sandbox violation: caller s3.amazonaws.com/bucket_name/swfs/MainSwf.swf cannot access LoaderInfo.applicationDomain owned by s3.amazonaws.com/bucket_name/data/swfs/foo/SecondSwf.swf

I've tried including/not including the context.applicationDomain = ApplicationDomain.currentDomain; line but that hasn't resolved the issue.

Where the crash is actually occurring is at a later time after the file is loaded where we are getting the applicationDomain: loader_.contentLoaderInfo.applicationDomain.getDefinition( def.a )

Was it helpful?

Solution

It looks like you have a.swf and b.swf on different domains, and a.swf is trying to access the content of b.swf (via Loader.content), and no doubt it's failing with a security error.

You have two options:

  1. Load b.swf in the same security domain as a.swf (i.e. the "current" security domain). You can do this in a.swf's code by passing a new LoaderContext to Loader.load() and setting the loaderContext.securityDomain = SecurityDomain.currentDomain

  2. Explicity allow a.swf to access b.swf by calling Security.allowDomain() in b.swf's code with a.swf's domain name as the parameter

Which one you choose depends on other considerations. With the first one, b.swf is able to do what a.swf can do (everything!) in terms of cross-domain security (i.e. access files, etc.); with the second one, any SWF file on a.swf's domain is able to access b.swf's content. It really depends how you want to set up the trust.

OTHER TIPS

Make sure the mime type of crossdomain.xml is set to application/xml. Flash will not load the policy file if the mime type isn't set correctly. Checkout CloudBerry's free s3 client, it's pretty good at detecting/setting the correct mimetype, its possible the s3 client you're using didn't set it correctly.

Edit: Apache, and other webservers, detect a file's mime type and return it in the response headers - so this issue doesn't normally come up in local testing

Solved, finally. Make sure you're using the bucket name as the subdomain for both the Policy file loading, and every file / URL request.

Solution:

http://onegiantmedia.com/cross-domain-policy-issues-with-flash-loading-remote-data-from-amazon-s3-cloud-storage

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top