到目前为止, 我们已经从单个 SWF 操作本身的角度讨论了本地安全性: 在用户未授权的情况下, 单个 SWF 不会同时具有本地读取和网络发送两种权限。但是当多个 SWF 彼此协同工作时, Flash Player 8 中的本地安全增强功能还必须能够保护 Flash Player 用户。SWF 的协作集 不能同时拥有本地读取和网络发送两种权限。
在 SWF 之间完成协作需要两个步骤。首先, 一个 SWF 必须加载另一个 (通常使用 ActionScript loadMovie 命令)。其次, 两个 SWF 必须交换信息 (可使用 ActionScript 变量、方法调用、LocalConnection 对象等)。这种信息交换有时被称为跨域脚本处理。
为维护本地安全, Flash Player 在某些情况下会禁止 SWF 的加载, 有时它允许加载 SWF 但是限制跨域脚本处理。
在位于相同沙箱的 SWF 之间将始终允许 SWF 加载和跨域脚本处理。例如, 任何供文件系统使用的本地 SWF 都可以加载其它任何供文件系统使用的本地 SWF, 并可以对它进行跨域脚本处理;任何供网络使用的本地 SWF 都可以加载其它任何供网络使用的本地 SWF, 并可以对它进行跨域脚本处理等。当来自不同沙箱的两个 SWF 尝试协作时, 将会显示限制。
表 1 总结了沙箱之间的加载和跨域脚本处理的限制, 其后显示各个规则。SWF 之间的任何协作都有两部分。我们将启动协作的 SWF (调用 loadMovie 或执行跨域脚本处理)称为访问 SWF, 将另一 SWF 称为被访问 SWF。该表顶部的标签表示访问 SWF 的沙箱, 左边的标签表示被访问 SWF 的沙箱。
| 访问 SWF 的沙箱 | ||||
|---|---|---|---|---|
| 被访问 SWF 的沙箱 | 供文件系 统使用的 本地沙箱 |
供网络 使用的 本地沙箱 |
受信任的 本地沙箱 |
远程沙箱 |
| 供文件系 统使用的 本地沙箱 |
加载: 允许 跨域脚本处理: 允许 |
加载: 不允许 | 加载: 允许 跨域脚本处理: 允许 |
加载: 不允许 |
| 供网络 使用的 本地沙箱 |
加载: 不允许 | 加载: 允许 跨域脚本处理: 允许 |
加载: 允许 跨域脚本处理: 允许 |
加载: 不允许 |
| 受信任的 本地沙箱 |
加载: 允许 跨域脚本处理: 需要权限 |
加载: 允许 跨域脚本处理: 需要权限 |
加载: 允许 跨域脚本处理: 允许 |
加载: 不允许 |
| 远程沙箱 | 加载: 不允许 | 加载: 允许 跨域脚本处理: 需要权限 |
加载: 允许 跨域脚本处理: 允许 |
加载: 允许 跨域脚本处理: 如果域不匹配, 则需要权限 |
表 1 中的红色单元格表示某些 SWF 无法加载其它 SWF 的情形 (使用 loadMovie、loadMovieNum 等):
必要时可以转化后两个规则, 因为很容易将 SWF 从供文件系统使用的本地 SWF 更改为供网络使用的本地 SWF, 反之亦然。
但是, 第一个规则, 即远程 SWF 不能加载本地 SWF, 是绝对的。与 Flash Player 中其它大多数安全规则不同, 它无法转化。该规则避免了所谓的区域扩大, 其中权限较少的区域 (远程 SWF)中的内容可激活具有更多潜在权限区域 (本地 SWF)的内容。如果发现自己处于一个维护混合的远程-本地应用程序的非寻常位置, 而该应用程序将在用户访问网页时启动本地安装的内容, 那么最好的选择是更改您的起点, 让用户通过查看随后激活联机内容的本地 SWF (或本地放映文件、本地可执行文件等)开始。
Flash Player 在调用 getURL 时具有类似规则, 即加载浏览器页面而不是 SWF:
表 1 中黄色的单元格表示某个 SWF 将可以对其它 SWF 进行脚本处理的情形, 条件是被访问 SWF 明确授予该操作的权限。这些情形包括:
为遵循 Flash Player 的全局权限原则, 其中前两种情形需要被访问 SWF 授予权限, 才能访问所有沙箱中的 SWF。这意味着要调用 System.security.allowDomain("*"), 或者对于 LocalConnection 对象, 则意味着要提供一个 LocalConnection.allowDomain 处理函数, 当为该函数提供指定“localhost.”的域参数时, 它将返回一个 True 值。
Flash Player 6 和更高版本通过 SharedObject 类支持永久共享对象。永久共享对象将数据存储在用户的计算机上。它们通常是通过 SharedObject.getLocal 获得的本地共享对象, 也可以创建永久远程共享对象;这需要 Flash Media Server* (以前为 Flash Communication Server), 在该产品中记录了远程共享对象。
每个远程沙箱对永久共享对象都有一个关联的存储。例如, 当来自 domain1.com 的任何 SWF 读取或写入永久共享对象时, Flash Player 将在 domain1.com 对象存储中读取或写入该对象。与此类似, 对于来自 domain2.com 的 SWF, Flash Player 将使用 domain2.com 存储。为避免名称冲突, 可通过路径进一步识别永久共享对象, 默认路径是创建 SWF 的 URL 全路径, 但是使用 SharedObject.getLocal 的 localPath 参数可缩短该路径, 该路径创建后将允许来自相同域的其它 SWF 访问共享对象。
在 Flash Player 7 和更早版本中, 所有本地 SWF 都共享一个永久共享对象存储。从 Flash Player 8 开始, 提供了两个本地共享对象存储。重复以前的模式, 通过将共享对象存储分别分配给这两种本地沙箱中的每一个, Flash Player 可以确保供文件系统使用的本地 SWF 不会与供网络使用的本地 SWF 通信。
Flash Player 将受信任的本地 SWF 分配到与供文件系统使用的本地 SWF 相同的共享对象存储。这可帮助简化供文件系统使用的状态 (默认)和受信任状态之间的转换 (这样最终用户可以按预期方式对停止运行的现有本地内容选择采取的修复措施)。当 SWF 执行这样的转换时, 它们将保留已创建的任何共享对象。