Silverlight 支持使用 HTTP/HTTPS (System.Net.WebClient 等) 和 Socket (System.Net.Sockets) 两种方式访问远程服务器,但基于安全原因,对这些网络访问制定了严格的安全策略。

1. HTTP/HTTPS 访问策略

(1) 始终允许同域调用。同域是指调用必须使用同一子域、协议和端口,这是出于安全原因以及防止跨域伪造。

(2) Silverlight 支持访问包含跨域策略文件的网站服务。跨域访问时,Silverlight Application 首先在目标 Web 服务的根路径查找 Silverlight 跨域策略文件 (clientaccesspolicy.xml)。如果没找到(404 Not Found)或发生其他错误,将继续在根路径处查找 Flash 跨域策略文件 (crossdomain.xml)。

clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>

(3) 所有通信都是异步的。

(4) 仅支持 GET 和 POST 谓词。

(5) 支持大多数标准请求标头和所有自定义请求标头(必须是跨域策略文件中允许的标头)。

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy >
<allow-from http-request-headers="SOAPAction, x-custom-header">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/services/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>

(6) 只有 "200 OK" 和 "404 Not Found" 状态代码可用。

我们尝试用 WebClient 访问一个跨域网站。

private void Button_Click(object sender, RoutedEventArgs e)
{
var client = new WebClient();
client.DownloadStringCompleted += (s, ex) =>
{
this.TextBlock1.Text = ex.Error != null ? ex.Error.ToString() : ex.Result;
};
client.DownloadStringAsync(new Uri("http://localhost:8081/", UriKind.Absolute));
}

当目标网站没有提供策略文件时,你会看到如下的错误信息。

在其根路径放置好 clientaccesspolicy.xml 后,访问正常。

2. Sockets 访问策略

创建一个供 Silverlight Application 连接的 Socket Server (非同域网站),必须符合以下安全策略。

(1) 监听 943 端口,为 Silverlight Application 提供策略文件(clientaccesspolicy.xml)。

(2) Socket Server 的服务端口范围必须在 4502 - 4534 之间。这是 Silverlight Application Socket 连接所允许使用的端口范围,否则连接失败。

我们写一个简单的 Time Server 作为演示。

Server CUI
class Program
{
static void Main(string[] args)
{
AccessPolicyServer();
TimeServer();
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
Environment.Exit(0);
}
/// <summary>
/// 创建时间服务器线程
/// </summary>
private static void TimeServer()
{
new Thread(() =>
{
// 监听 4502 端口
var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 4502);
server.Start();
while (true)
{
var client = server.AcceptTcpClient();
var stream = client.GetStream();
// 发送当前时间
var send = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
stream.Write(send, 0, send.Length);
client.Close();
}
}).Start();
}
/// <summary>
/// 创建策略文件服务器线程
/// </summary>
private static void AccessPolicyServer()
{
new Thread(() =>
{
// 监听 943 端口
var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 943);
server.Start();
while (true)
{
var client = server.AcceptTcpClient();
var stream = client.GetStream();
// 读取客户端发送信息,如果请求字符串不匹配则断开。
var buffer = new Byte[1024];
var len = stream.Read(buffer, 0, buffer.Length);
var rece = Encoding.UTF8.GetString(buffer, 0, len);
if (String.Compare(rece, "<policy-file-request/>", true) != 0)
{
client.Close();
break;
}
Console.WriteLine(rece);
// 发送策略文件内容
var send = Encoding.UTF8.GetBytes(@"
<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri=""*""/>
</allow-from>
<grant-to>
<socket-resource port=""4502-4534"" protocol=""tcp"" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>");
stream.Write(send, 0, send.Length);
client.Close();
}
}).Start();
}
}
Client Silverlight XAP
private void Button_Click(object sender, RoutedEventArgs e)
{
// 创建 Socket
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 创建等待句柄
var wait = new ManualResetEvent(true);
// 创建连接参数
var args = new SocketAsyncEventArgs();
args.RemoteEndPoint = new DnsEndPoint("127.0.0.1", 4502);
// 订阅处理事件
args.Completed += (s, ex) =>
{
if (ex.LastOperation == SocketAsyncOperation.Connect)
{
// 连接完成,则设置缓冲区
var buffer = new byte[1024];
ex.SetBuffer(buffer, 0, buffer.Length);
// 接收服务器数据
client.ReceiveAsync(ex);
}
else if (ex.LastOperation == SocketAsyncOperation.Receive)
{
// 如果接收信息正确,则显示服务器发送内容,否则显示错误信息。
if (ex.SocketError == SocketError.Success)
{
this.Dispatcher.BeginInvoke(() =>
{
this.TextBlock1.Text = Encoding.UTF8.GetString(ex.Buffer, 0, ex.BytesTransferred);
});
}
else
{
this.Dispatcher.BeginInvoke(() =>
{
this.TextBlock1.Text = ex.SocketError.ToString();
});
}
wait.Set();
}
};
// 连接服务器
client.ConnectAsync(args);
// 等待处理结束
wait.WaitOne();
}

如果不启动服务器策略文件服务,或者端口不是 943,你会在客户端获得一个 AccessDenied 错误。

当然,如果服务器监听端口不再允许范围(4502 - 4534)内,同样也会触发这样一个错误。

【reprinted from http://www.rainsts.net/】

Silverlight 中的通信安全访问策略相关推荐

  1. 入门篇:函数计算中角色和访问策略的讲解

    阿里云函数计算是近期推出的一个无服务器的全托管的产品,使用者只需编写核心代码并设置运行的条件,即可在函数计算以弹性.安全地运行.函数计算能自行维护服务器资源,网络资源,以及消息分发和负载均衡等功能. ...

  2. 技巧:在Silverlight中如何访问外部xap文件中UserControl

    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://terrylee.blog.51cto.com/342737/87094 ...

  3. Silverlight中调用WebService-发送邮件测试实例

    Silverlight能够构建强大的企业级应用程序,关键和Silverlight2.0强大数据通信是分不开的,包括SOAP服务的访问,RESTful服务的访问,以及基于Http协议和Socket通信等 ...

  4. DNN 数据访问策略 (转)

    经过几天断断续续的努力,这篇文章终于翻译结束,文章主要讲了DNN的数据访问策略,对于了解系统整体上是如何工作的有一定的帮助,希望能给dnn的初学者一些有用的信息.由于翻译的匆忙+水平有限,错误或不当之 ...

  5. Silverlight中使用CompositionInitializer宿主MEF

    MEF可以在传统应用程序中使用(包括桌面的Winform.控制台程序和Web的ASP.NET),也可以在RIA的Silverlight中使用.在Silverlight中只是宿主的方式有所不同,实际上在 ...

  6. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地

    在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silv ...

  7. 十步优化SQL Server中的数据访问

    故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...

  8. 如何配置天融信NGFW4000防火墙基于长连接的访问策略

    a. 假设你已经通过串口初始化了防火墙4000(配置接口IP.GUI 登录权限等),并按照以上拓扑图连接好网络.创建了相关网络对象(如有疑问请参看"防火墙4000 管理配置"和&q ...

  9. 数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一)

    数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一) 步骤: 1. 创建SILVERLIGHT应用程序 2. 创建LINQ TO SQL [注意序列化的问题 ...

最新文章

  1. hdu-1041(大数模板)
  2. Install marvel and head plugin for ealsticsearch
  3. 南丁格尔邮票图片大全_【鉴赏】武夷山普通纪念币鉴赏(高清图片)
  4. vb.net 正則表達式 取 固定格式的字符
  5. HbuilderX如何创建一个新的Vue工程
  6. 外贸单证管理可高效简化外贸进出口制单流程
  7. NOJ——[1480] 懒惰的风纪委Elaine
  8. java servlet mysql_servlet+mysql实现简易的登录功能
  9. 裸金属服务器能降级虚拟机不,裸金属服务器属于虚拟机吗
  10. PRACH, preamble, RO 的关系与区别
  11. 六西格玛奠基人之张驰染阳杂记
  12. 美国Linux服务器系统增强安全的配置
  13. CSS 关键字 inherit 和 unset
  14. 快手AI 实验室Y-Lab 招聘
  15. Uncaught TypeError: ‘set‘ on proxy: trap returned falsish for property ‘visible‘
  16. vue---安装使用vue-layer弹框插件
  17. 实验七 集成功率放大电路
  18. Debian 9 安装 NVIDIA显卡驱动
  19. 教你用msconfig命令设置开机启动项
  20. Skywalking内置Tags

热门文章

  1. cf修改游戏客户端是什么意思_cf游戏客户端是什么
  2. 数据结构与与算法之插入排序
  3. oracle 分页_Mybatis:PageHelper分页插件源码及原理剖析
  4. macos无法验证此app不包含恶意软件_macOS 平台的一款后门样本(TinyTim)的分析
  5. Halcon图像预处理与形态学(图像的滤波)
  6. Python: 分数运算
  7. 虚拟机中CentOS系统安装流程
  8. Jupyter Notebook安装jupyter_contrib_nbextension扩展功能和安装后不显示Nbextensions标签的解决办法
  9. Apache阶段二-
  10. 每个人都应该了解的HTTPS知识