[转]关于Flex安全沙箱问题的解决
前些天做了一个flex的小程序,通过访问服务前端的xml来更新数据,在本地调试调用本地的xml文件是没有问题的,可把url换成服务器端时就出现了Security Error,通过上网查找断定是安全沙箱的问题,下面是在网上找到的解决安全沙箱问题的方法,仅供参考。
方法一:在目标服务器上布署crossdomain.xml文件(我用的此方法很管用,放上就没问题了) 需要远程服务根目录定义有crossdomain.xml文件,如下:
<?xml version="1.0" encoding="UTF-8" ?> <cross-domain-policy> <allow-access-from domain="*"/> </cross-domain-policy>
方法二:使用代理,把Flex要访问的远程文件通过asp, php, jsp等脚本读取到本地,然后再由Flex去访问;
方法三:使用Adobe flash player 9 打开程序后,点击菜单栏中文件->创建播放器...即生成exe文件,运行exe文件即可突破安全限制;
方法四: 1、找到这个文件夹:c:\Documents and Settings\<UserName>\Application Data\Macromedia\Flash Player\#Security 2、在其下建立一个名为"FlashPlayerTrust"的文件夹 3、在"FlashPlayerTrust"文件夹下新建一TXT文件,内容如下: c:\ d:\ e:\ f:\ 4、将该txt文件命名为:"myTrustFiles.cfg" 再打开你硬盘里的SWF文件,就不会出现那个烦人的安全设置提示窗口了!
方法五: 用HttpService它默认是有Proxy的,需要配置flex-config.xml,里面有一段: <http-service-proxy> <whitelist> ……………… </whitelist> </http-service-proxy>
这个是白名单,一般情况下是注释掉的,也就是默认只有本地的http://{localserver}/*和https://{localserver}/*可以访问。其他的需要在flex-config.xml里的自行修改成需要的就可以了。
访问本地自然不会跨域,不过你肯定访问局域网其他机器了,所以是依照白名单规则,属于跨域
Socket沙箱问题
在Flex中使用Socket进行通信时,也会受到Flash9的新安全策略的困扰. 解决方法不能像在Web服务器中布置一个crossdomain.xml来解决,或是在服务器上专门开启843端口来提供安全策略. 有一种方法就是在接收到客户端的连接后,向其发送 安全策略.
比如我是用JAVA来开发, 客户端的Flex会先搜索同域,及服务器的843口,看是否能得到安全策略,这时候Socket是先建立好的,可以在接收到Socket ,即Accept事件发生是,马上向其发送 策略串,否则客户端就会因为安全策略不过关,于断开, 如果成功获取策略,则客户端将断掉先前的那次Socket, 再真正进行程序中你要求的Socket连接请求.
下面看看我找的例子吧!
public void run() {
ServerSocket ss;
String ip = "";
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
String xml = "<cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/>";
xml = xml + "<allow-access-from domain=\"" + ip + "\" to-ports=\"1234\" />";
xml = xml + "</cross-domain-policy>";
try {
ss = new ServerSocket(port);
while (!cancle) {
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s
.getInputStream(), "UTF-8"));
PrintWriter pw = new PrintWriter(s.getOutputStream());
char[] by = new char[22];
br.read(by, 0, 22);
String head = new String(by);
//判断是不是第一求请求连接的安全验证,当客户端连socket时,as3会自动向服务端发送<policy-file-request/>这个字符串请求返回策略文件,所以当服务器收到这个串后给client返回就好了。
//如果是返回xML信息
if (head.equals("<policy-file-request/>")) {
System.out.println("连接服务器");
pw.print(xml + "\0");
pw.flush();
br.close();
pw.close();
} else {
//你自己的正常请求处理逻辑
}
}
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
<http-service-proxy>
..........................
<whitelist>
<!-- whitelist config for unnamed services -->
<unnamed>
<url>http://{localserver}/*</url>
<url>https://{localserver}/*</url
..............................................
</unnamed>
<!-- whitelist config for named services -->
<named>
....................
<service name="SampleEmployeeSrv">
<url>{context.root}/explorer/data/employees.jsp</url>
<use-custom-authentication>true</use-custom-authentication>
</service>
................................................
再看在flex目录下的 flex-config.xml文件
<whitelist>
<!-- whitelist config for unnamed services -->
<unnamed>
<url></url>
<!--
For security, the whitelist is locked down by default.
Uncomment the first two urls below to enable access to all URLs,
or the last two urls to enable access to the local server,
or add above the individual URLs you wish to access.
<url>http://*</url>
<url>https://*</url>
<url>http://{localserver}/*</url>
<url>https://{localserver}/*</url>
-->
</unnamed>
<!-- whitelist config for named http services -->
<!-- <named> -->
<!-- define an http service which may be referenced by name from mxml -->
<!-- <service name="service"> -->
<!-- enables use of custom fault code on the client for handling authentication failures -->
<!-- <use-custom-authentication>false</use-custom-authentication> -->
<!-- actual url to use when accessing the named http service -->
<!-- <url>http://localhost:8100/flex/servicename</url> -->
<!-- user-name and password to use when accessing this http service -->
<!-- <run-as user="user" password="pwd"/> -->
<!-- Adds the service's url to the unnamed whitelist. If false, these can never be used unnamed -->
<!-- This should be set to false if using web application security with this named service -->
<!-- <allow-unnamed-access>true</allow-unnamed-access> -->
<!-- </service> -->
<!-- </named> -->
</whitelist>
于是,我把
<url>http://*</url>
<url>https://*</url>
<url>http://{localserver}/*</url>
<url>https://{localserver}/*</url>
这段的注释符去掉就可以了。
还有一种访问servlet的方法就是通过named来的,如在上面<named>...</named>加上
<service name="ServletService">
<url>{context.root}/servlet/XMLFacadeServlet</url>
<use-custom-authentication>true</use-custom-authentication>
</service>
mxml这样使用:
<mx:HTTPService id="ServletService1" serviceName="ServletService">
mx:HTTPService 需要一个send操作才能执行发送GET或POST命令以获得数据,如:
<mx:Button label="Get Employee List" click="employeeSrv.send();"/>
修改flex-config.xml后要重起tomcat的,如果你修改后flex-config.xml存在问题(如:把named写成name),
访问mxml的时候就会出现 url is not available 这个错误了