在Adobe Flash Player升级到9.0.124后,由于安全策略更改,原来Socket或XmlSocket的应用里的http方式加载安全策略的手段不能继续使用。更改如下:
1,首先检测目标服务器的843端口是否提供安全策略
2,如果1没有检测到策略,则检测actionscript是否使用了Security.loadPolicyFile(xmlsocket://) 手段提供安全策略,如果还没检测到,则使用第3步检测
3,检测目标服务器目标端口是否提供安全策略。
在说具体处理方式前,我先描述一下Flash Player的验证过程。在Flex程序发出Socket或XmlSocket(以下统称为Socket)请求前,FlashPlayer会先判断是否为本地调用,如果不是。即用一个Socket去链接到你的服务端,三次握手成功后一方面发出字符串“<policy-file- request/>\0“另一方面监听返回的安全策略。安全策略接收成功后,FlashPlayer就断开验证的Socket,然后再运行程序本身的Socket。在整个SWF运行期间,无论你请求多少次,只要域相同,FlashPlayer就只验证一次。这里有两个重点,
第一个是验证的Socket和程序的Socket是两个Socket。所以你在本地测试时,服务端监听到N个Socket请求,但布置到服务端后,服务端会监听到N+1个请求。
第二是验证的Socket发送<policy-file-request/>\0“请求和接收你的策略文件是没有先后关系的,所以你没必要接收完“<policy-file-request/>\0“后才发策略文件。我的做法是只要监听到请求,就把策略字符串发过去。
上面提供了三种方式处理安全策略。处理的办法差不多一样,就是要求服务端监听一个端口,如果客户端发来“<policy-file-request/>\0“请求,服务端就要返回你的安全策略的字符串。
其实三种处理方式的主要区别在于监听端口,方法1和2要求在另外的端口监听,而第三个即在应用本身监听的端口监听。其实监听端口的数量多一个不如少一个。在虚拟空间中不说了,端口不是说要监听就监听的,要有权限。就算有权限监听,还要防火墙同意。所以我比较偏向于第三种。
下面是我的测试服务器端代码(C#)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Xml;
namespace Server
{
class Program
{
static void Main(string[] args)
{
try
{
int port = 60002;
string host = "192.168.1.103";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket类
s.Bind(ipe);
s.Listen(0);
Console.WriteLine("Wait for connect 60002");
while (true)
{
try
{
Socket temp = s.Accept();//为新建连接创建新的Socket。
Console.WriteLine("Get a new connect " + DateTime.Now.ToString());
string recvStr = "";
byte[] recvBytes = new byte[1024];
int bytes;
bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息
recvStr += Encoding.GetEncoding("UTF-8").GetString(recvBytes, 0, bytes);
Console.WriteLine("Server Get Message: {0}", recvStr);//把客户端传来的信息显示出来
if (recvStr == "<policy-file-request/>\0")
{
String sendStr = "<cross-domain-policy><allow-access-from domain=\"192.168.1.102\" to-ports=\"60000-60010\"/></cross-domain-policy>\0";
byte[] bs = Encoding.GetEncoding("UTF-8").GetBytes(sendStr);
temp.Send(bs, bs.Length, 0);//返回客户端成功信息
Console.WriteLine("Send: " + sendStr);
//temp.Close();
//s.Close();
}
else
{
string sendStr = "Ok!Client Send Message Sucessful!";
byte[] bs = Encoding.GetEncoding("UTF-8").GetBytes(sendStr);
temp.Send(bs, bs.Length, 0);//返回客户端成功信息
//temp.Close();
//s.Close();
}
}
catch (Exception ex)
{
Console.WriteLine("SocketException: {0}", ex);
}
}
}
catch (Exception ex2)
{
Console.Write(ex2.Message.ToString());
}
}
}
}