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 )
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
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:
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
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.
Related
I'm using dropbox to distribute large swf files with corresponding html files that load the swfs. All the large swf files access a small "Key" swf in the same folder as the html file. That all works fine. But when the large swf files also try to access a remote text file on my server I get a security sandbox violation. After reading about this, I see that this is by design for security reasons.
But there has to be a way around this without having the user authorize the domain containing the txt file. The reason I say this is because the swf files are running right from the browser on the persons computer. I then thought about a cross domain policy. Not sure what it would look like since it's a local computer that's asking. I hope this makes sense. I was hoping I could put the cross domain policy (or some other file) on the users computer right along with the other files, but I don't think that's what they're for.
This is an update to the question above as my problems relate to crossdomain policy's. I'm showing a small snippet of code that is causing this error shown in Debug mode in the Flash IDE. The code eventually gets the txt file loaded, but is delayed due to the warning I believe and I'm wondering if this can be fixed? The delay is causing an issue.
Attempting to launch and connect to Player using URL C:\Users\Jeffrey\Dropbox\Photos\ABC\bopAnimationSales\testingGettingVariablesFromExternalSWF_simplestForm3.swf
[SWF] C:\Users\Jeffrey\Dropbox\Photos\ABC\bopAnimationSales\testingGettingVariablesFromExternalSWF_simplestForm3.swf - 21834 bytes after decompression
Warning: Domain www.postureviewer.com does not specify a meta-policy. Applying default meta-policy 'master-only'. This configuration is deprecated. See http://www.adobe.com/go/strict_policy_files to fix this problem.
Complete
[UnloadSWF] C:\Users\Jeffrey\Dropbox\Photos\ABC\bopAnimationSales\testingGettingVariablesFromExternalSWF_simplestForm3.swf
Debug session terminated.
Here's the code:
import flash.events.*;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.system.Security;
//flash.system.Security.loadPolicyFile("http://www.postureviewer.com/trials/crossdomain.xml");
var urlRequest:URLRequest = new URLRequest("http://www.postureviewer.com/trials/jeffaberle.txt" + "?" + Math.random()); // + Math.random()
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
urlLoader.load(urlRequest);
function completeHandler(e:Event):void {
trace("Complete");
}
function ioErrorHandler(e:IOErrorEvent):void {
trace("ioErrorHandlerJeff: " + e.toString());
licenseKeyNotFoundScreen.visible = true;
}
To authorize your local swf file to access to a remote content ( a text file in your server in your case ), you don't need a crossdomain.xml file that
grants a web client—such as Adobe Flash Player, Adobe Reader, etc.—permission to handle data across multiple domains
So in your case, when using a local swf to get data from a remote location, you have just to add your swf to the list of trusted locations like I explained in my answer of this question.
Hope that can help.
You can load a cross domain policy from an arbitrary location via "loadPolicyFile"
I would recommend hosting it at the same location as the remote text file to keep things simple, i.e.
http://www.example.com/clients/clientfile.txt
http://www.example.com/clients/crossdomain.xml
Then in the 'big' SWF, import the Flash Security package if you are not using it already:
import flash.system.Security;
Then before making any calls remote calls to load data content from your local based SWF, call loadPolicyFile:
flash.system.Security.loadPolicyFile("http://www.example.com/clients/crossdomain.xml");
Then you will be able to call URLRequest, etc... without any issues:
urlRequest = new URLRequest("http://www.example.com/clients/clientfile.txt");
Your crossdomain.xml should look like this:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="www.example.com/clients"/>
</cross-domain-policy>
PS: An online cross domain generator is # http://www.crossdomainmaker.com Helps prevent typos and that painful head scratching when yours does not work... ;-)
PSS: Personally for local SWFs, I prefer AIR packaging as it eliminates the cross-domain issues, no browser is required, etc... Only one file that contains all your other SWFs as resources that can be deploy as an '.air' file or via a native Windows installer (exe) or OS-X dmg and .app installer.
I'm trying to play a Youtube video through my flash project. The video plays but I get the error below and it ruins the rest of my project. I couldn't find anywhere that had this exact error. Ive been trying to understand what it's telling me but I just cant wrap my head around it.
Error:
*** Security Sandbox Violation ***
SecurityDomain 'http://s.ytimg.com/yts/swfbin/apiplayer3-vflmoXxFm.swf'
tried to access incompatible context 'file:flashProject.swf'
Here's the code I have for the player:
Security.allowDomain("www.youtube.com");
var my_player:Object;
var my_loader:Loader = new Loader();
my_loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
my_loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
function onLoaderInit(e:Event):void{
addChild(my_loader);
my_player = my_loader.content;
my_player.addEventListener("onReady", onPlayerReady);
}
function onPlayerReady(e:Event):void{
my_player.setSize(600,300);
my_player.cueVideoById("76BboyrEl48",0);
my_player.x = stage.stageWidth/2 - my_player.width/2;
my_player.y = stage.stageHeight/2 - my_player.height/2;
}
This is part of my Final Year college project so if anyone has any ideas Id be more than happy to give it a try. Thanks in advance :)
For security reasons FlashPlayer separates two sandboxes local and remote(network). At time you are only allowed to use one of them, you cannot load content from both same time. Every swf loaded from local file-system is considered in local sandbox, everything other is considered in network sandbox.
So now your swf is loaded from file-system not from web-server and flash considers it in local sandbox, then your swf loads content from remote/network sandbox i.e. from www.youtube.com, as I mentioned above, swf running in local sandbox cannot load content from remote sandbox and same for swf in remote sandbox cannot load content from local sandbox. So error is natural.
allowDomain() only allows different domains from same sandbox i.e. you can load content from www.youtube.com to into swf loaded from www.yourdomain.com
Form more info about security sandboxes see this: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3f.html
Now to fix your problem:
1) You can setup local HTTP server locad swf from localhost.
2) Or you can put your swf in local trusted swf list. Only local trusted swf are allowed to load content from both sandboxes at same time. See link below for info how to put your swf in local trusted list.
http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3f.html
try including a cross-domain.xml file like the one shown below on your project.
<?xml version="1.0"?>
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*"/>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
Otherwise try adding your content here under the security settings panel.
http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html
for more about security sandbox refer: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3f.html
I'm a complete noob when it comes to flash coding.
I have a flash swf file that I'm loading from an S3 assets bucket. Inside the flash swf it should be displaying a "Browse" button, images also courtesy of the same bucket. This works fine when I host the images and swf file from the same domain that the site is on, but not when loaded from S3.
I have added a crossdomain.xml file to the assets bucket as follows (I'm trying with '*' to start just to get it working, and will narrow it down to my actual host when it appears to be doing anything):
<?xml version="1.0"?>
<!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>
I also have a cross-origin resource sharing configuration in the bucket so that the fonts will correctly load for our stylesheets (This is working).
What am I doing wrong to make the button images load in the actionscript? Do I need to modify the actionscript code itself? The code is located here (public library anyone can use, not authored by me): s3-swf-upload-plugin
You can see here that it is instantiating a new browseButton defined here. Like I said I'm not totally familiar with actionscript but believe I could fumble through it if someone could show me what's going wrong :) What's a good way to get actual error reporting? Firebug in Firefox and Chrome's console don't have any kind of messages from Flash about errors going on.
EDIT:
There were some quirkinesses going on in the setting up of the flash object and setting the paths for the button images. I updated BrowseButton.as to do this:
Security.loadPolicyFile("http://s3.amazonaws.com/my-bucket/crossdomain.xml");
I placed this before any of the URLRequest calls in the BrowseButton() function. However it's still not displaying the images :( I also hardcoded the values in the URLRequest to be things like:
upLoader.load(new URLRequest("http://s3.amazonaws.com/my-bucket/assets/s3_up_button.gif"));
but nothing seems to happen. When I set it to /assets/s3_up_button.gif to pull from the local file then it works fine. What am I doing wrong! How can I get error messages displaying from the flash video? :\ I compiled with <debug>true</debug> but I'm not sure how to get actual exception messages.
Check what sandbox your swf is in:
The Security.sandboxType property
An author of a SWF file can use the read-only static
Security.sandboxType property to determine the type of sandbox to
which Flash Player has assigned the SWF file. The Security class
includes constants that represent possible values of the
Security.sandboxType property, as follows:
Security.REMOTE--The SWF file is from an Internet URL, and operates under domain-based sandbox rules.
Security.LOCAL_WITH_FILE--The SWF file is a local file, but it has not been trusted by the user and was not published with a networking designation. The SWF file can read from local data sources but cannot communicate with the Internet.
Security.LOCAL_WITH_NETWORK--The SWF file is a local file and has not been trusted by the user, but it was published with a networking designation. The SWF can communicate with the Internet but cannot read from local data sources.
Security.LOCAL_TRUSTED--The SWF file is a local file and has been trusted by the user, using either the Settings Manager or a Flash Player trust configuration file. The SWF file can both read from local data sources and communicate with the Internet.
You probably want Security.LOCAL_WITH_NETWORK, although Security.LOCAL_TRUSTED will also work.
An explanation, along with details of how to set the sandbox in Flex, is here: http://livedocs.adobe.com/flex/3/html/help.html?content=05B_Security_04.html
If you're working in the Flash IDE, it should just be part of the publish settings.
Two important points.
1 - SWF must have ability to loading binary data from any domain.
2 - SWF cant load policy XML file from url, cause upload form allows me only to upload swf files, so I cant include any other data.
I tried:
Security.allowDomain("*");
But it works only for SWF files.
I tried to embed policy XML file:
var dataXML:XML =
<?xml version="1.0"?>
<!-- http://www.foo.com/crossdomain.xml -->
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>;
But Security.loadPolicyFile(url:String) allows only to set file url, not data.
So my question is, how can I allow SWF to load binary files from different domains without having any additional file?
URLLoader code:
var request:URLRequest = new URLRequest("http://differentdomain.com/binaryfile.dat");
var words:URLLoader = new URLLoader();
words.dataFormat = URLLoaderDataFormat.BINARY;
words.addEventListener(Event.COMPLETE, prepareFile);
words.addEventListener(IOErrorEvent.IO_ERROR, loadError);
words.addEventListener(SecurityErrorEvent.SECURITY_ERROR, secureError);
words.load(request);
This will make an security error, if file is from different domain than SWF file.
Thanks for any help.
Its possible to get binary data from JavaScript using ExternatInterface in AS3 code.
Here is cross-browser library for reading files binary: binary reader and later version jDataView
Hope this will help someone.
Thanks to Jonatan Hedborg for idea.
You should read this before : http://kb2.adobe.com/cps/142/tn_14213.html
And you can use a proxy script, search on google/stackoverflow you'll find a lot of answers...
Take a look at this: http://wonderfl.net/c/gJXA
Some trick which works with any binary data from any domain, without need to use ajax or own proxy script (sometimes you dont have possibility to upload php scripts).
Flash is control that most commonly used by HTML pages. As result it needs to follow security restrictions places on other (i.e. JavaScript) objects on the same page.
Web pages use same origin security policy - objects on a page can't read data from domains different from domain of the current page.
There are cases when servers for other domains allow such access. I.e. in Flash case it is crossdomain.xml, similar policy file exist for Silverlight, there are several ways to handle it for JavaScript including JSONP.
Incorrect usage of ways to bypass same origin policy leads to cross-site scripting issues on your site/page that host your control which often leads to leaking personal information.
I had to tackle a similar problem a while ago and managed to make use of UrlStream to load the target SWF's bytes at runtime.
gist: https://gist.github.com/1988661
So as I stated in this other post my MP3 Player is not loading online, but works perfectly on my local computer.
I was messing around with files today and I finally got flash to give me an error. Could this be why the MP3 player does not load online? Here's the error:
TypeError: Error #2007: Parameter text must be non-null.
at flash.text::TextField/set text()
at Mp3Player_fla::MainTimeline/id3Handler()
By the way I have the MP3 on its own swf. Its being called by the main swf. If I place all the code into the main swf could it possibly work? That should'nt make a difference, but maybe because I'm loading large movies as the backgrounds and many other swf's at the same time, its messing it up?
The MP3 Player I was using on my site was developed by FlashXML and initially I had the same kind of problem, but I talked with the guys from FX and they sorted my problems out.
Was really stuck untill they helped me. If you are still interested, you can check it out at www.flashxml.net/mp3-player.html
Your bug is in the id3Handler function. It appears you are trying to set the value of a text field there to null. If you cant figure it out, post the code for id3Handler and I'll give you some more info. Likely something hasn't loaded yet.
You could try to catch the error in the id3Handler , in case the id3 tags are not defined
function id3Handler(evt:Event):void {
try{
songInfo.text = /*song.id3.artist + ": " +*/ song.id3.songName;
}catch(e:Error)
{
trace(e );
//or...
songInfo.text = "No name"
}
}
although , you may well have a security issue , id3 info would be returned in such case. do you use a crossdomain policy file?
Extract from the Sound class docs:
Certain operations dealing with sound are restricted.
The data in a loaded sound cannot be accessed by a file in a different domain
unless you implement a cross-domain policy file.
Sound-related APIs that fall under this restriction are
Sound.id3 ,
SoundMixer.computeSpectrum(),
SoundMixer.bufferTime,
and the SoundTransform class.
Edit:
Here's a very permissive policy file, copy it , save it to a file and name the file
crossdomain.xml
then upload it to the root folder of your site, for instance for example.com
http://example.com/crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy> <site-control permitted-cross-domain-policies="all"/>
<allow- access-from domain="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>
If this works, read this article
http://kb2.adobe.com/cps/142/tn_14213.html
and see how you can secure your site with the crossdomain policy file