Writing Flash crossdomain.xml for Amazon S3



我有两个服务器。服务器A是一个内部服务器,可以从外部世界访问,设置在我的办公室。它有一个运行在上面的Rails服务器。我有第二个服务器,服务器B,它包含我们所有的静态内容(图像、swfs、javascript、css等),它是一个AmazonS3服务器。我已经允许公众访问所有这些文件。

我试图将服务器B中的swf放在服务器a提供的页面上。然后,swf显示所需的其他资产从服务器B中动态加载。然而,不幸的是,在这一过程中,它出现了故障,请求动态加载的文件永远不会到达。

根据我的浏览器控制台中的错误,swf希望在服务器a上有一个crossdomain.xml文件。基于此,它还需要在我的S3服务器上有一份。因此,在这种情况下,我创建了两个crossdomain.xml文件,每个服务器一个。

这是服务器A的crossdomain.xml文件:

<?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>

这是服务器B的crossdomain.xml文件:

<?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>

此外,我正在swf:中显式加载服务器B的crossdomain.xml文件

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

然而,无论我做什么,它都不起作用。我不知道还能尝试什么。我试着在SO上查找了许多解决方案,但还并没有什么能帮助我解决问题。当然,其他人在这方面比我有更多的经验,可以给我一些指导,我在这一点上几乎没有想法。

更新用更多信息更新我的问题。

我尝试将两个策略文件都设置为*,它开始工作,直到它命中:

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.

此外,我运行了Charles,它正在从我的两个本地服务器中提取crossdomain.xml,但我在s3中看不到它。

更新2我试着把这个添加到加载器中:

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

这导致文件实际下载!不幸的是,现在它崩溃了:

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

我尝试过包含/不包含context.applicationDomain = ApplicationDomain.currentDomain;行,但这并没有解决问题。

实际发生崩溃的地方是在加载文件后的稍后时间,我们将在那里获得应用程序域:loader_.contentLoaderInfo.applicationDomain.getDefinition( def.a )

确保crossdomain.xml的mime类型设置为application/xml。如果mime类型设置不正确,Flash将不会加载策略文件。检查CloudBerry的免费s3客户端,它非常善于检测/设置正确的mimetype,可能您使用的s3客户端没有正确设置它。

编辑:Apache和其他Web服务器检测文件的mime类型并将其返回到响应标头中,因此在本地测试时通常不会出现此问题

最终解决。确保您使用bucket名称作为策略文件加载和每个文件/URL请求的子域。

解决方案:

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

看起来你在不同的域上有a.swf和b.swf,a.swf正试图访问b.swf的内容(通过Loader.content),毫无疑问,它因安全错误而失败。

你有两个选择:

  1. 在与a.swf相同的安全域(即"当前"安全域)中加载b.swf。您可以在.swf的代码中通过将新的LoaderContext传递给Loader.load()并设置loaderContext.securityDomain = SecurityDomain.currentDomain 来实现这一点

  2. 使用a.swf的域名作为参数,通过调用b.swf代码中的Security.allowDomain(),显式允许a.swf访问b.swf

你选择哪一个取决于其他因素。有了第一个,b.swf就可以在跨域安全(即访问文件等)方面做a.swf能做的事情(一切!);使用第二个,a.SWF域上的任何SWF文件都可以访问b.SWF的内容。这实际上取决于你想如何建立信任。

最新更新