Silverlight 中的通信安全访问策略

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

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

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
<?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) 支持大多数标准请求标头和所有自定义请求标头(必须是跨域策略文件中允许的标头)。

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
<?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 访问一个跨域网站。

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
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

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
  1class Program
  2img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif{
  3  static void Main(string[] args)
  4img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif  {
  5    AccessPolicyServer();
  6    TimeServer();
  7
  8    Console.WriteLine("Press any key to exit");
  9    Console.ReadKey(true);
 10    Environment.Exit(0);
 11  }

 12
 13img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif  /**//// <summary>
 14  /// 创建时间服务器线程
 15  /// </summary>

 16  private static void TimeServer()
 17img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif  {
 18    new Thread(() =>
 19img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    {
 20      // 监听 4502 端口
 21      var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 4502);
 22      server.Start();
 23
 24      while (true)
 25img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif      {
 26        var client = server.AcceptTcpClient();
 27        var stream = client.GetStream();
 28
 29        // 发送当前时间
 30        var send = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
 31        stream.Write(send, 0, send.Length);
 32
 33        client.Close();
 34      }

 35    }
).Start();
 36  }

 37
 38img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif  /**//// <summary>
 39  /// 创建策略文件服务器线程
 40  /// </summary>

 41  private static void AccessPolicyServer()
 42img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif  {
 43    new Thread(() =>
 44img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    {
 45      // 监听 943 端口
 46      var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 943);
 47      server.Start();
 48
 49      while (true)
 50img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif      {
 51        var client = server.AcceptTcpClient();
 52        var stream = client.GetStream();
 53        
 54        // 读取客户端发送信息,如果请求字符串不匹配则断开。
 55        var buffer = new Byte[1024];
 56        var len = stream.Read(buffer, 0, buffer.Length);
 57
 58        var rece = Encoding.UTF8.GetString(buffer, 0, len);
 59        if (String.Compare(rece, "<policy-file-request/>"true!= 0)
 60img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        {
 61          client.Close();
 62          break;
 63        }

 64
 65        Console.WriteLine(rece);
 66
 67        // 发送策略文件内容
 68        var send = Encoding.UTF8.GetBytes(@"
 69          <?xml version=""1.0"" encoding=""utf-8""?>
 70          <access-policy>
 71            <cross-domain-access>
 72              <policy>
 73                <allow-from>
 74                  <domain uri=""*""/>
 75                </allow-from>
 76                <grant-to>
 77                  <socket-resource port=""4502-4534"" protocol=""tcp"" />
 78                </grant-to>
 79              </policy>
 80            </cross-domain-access>
 81          </access-policy>");
 82
 83        stream.Write(send, 0, send.Length);
 84
 85        client.Close();
 86      }

 87    }
).Start();
 88  }

 89}

 90
 91Client Silverlight XAP 
 92
 93private void Button_Click(object sender, RoutedEventArgs e)
 94img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif{
 95  // 创建 Socket
 96  var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 97
 98  // 创建等待句柄
 99  var wait = new ManualResetEvent(true);
100  
101  // 创建连接参数
102  var args = new SocketAsyncEventArgs();
103  args.RemoteEndPoint = new DnsEndPoint("127.0.0.1"4502);
104
105  // 订阅处理事件
106  args.Completed += (s, ex) => 
107img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif  {
108    if (ex.LastOperation == SocketAsyncOperation.Connect)
109img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    {
110      // 连接完成,则设置缓冲区
111      var buffer = new byte[1024];
112      ex.SetBuffer(buffer, 0, buffer.Length);
113
114      // 接收服务器数据
115      client.ReceiveAsync(ex);
116    }

117    else if (ex.LastOperation == SocketAsyncOperation.Receive)
118img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    {
119      // 如果接收信息正确,则显示服务器发送内容,否则显示错误信息。
120      if (ex.SocketError == SocketError.Success)
121img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif      {
122        this.Dispatcher.BeginInvoke(() =>
123img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        {
124          this.TextBlock1.Text = Encoding.UTF8.GetString(ex.Buffer, 0, ex.BytesTransferred);
125        }
);
126      }

127      else
128img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif      {
129        this.Dispatcher.BeginInvoke(() =>
130img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        {
131          this.TextBlock1.Text = ex.SocketError.ToString();
132        }
);
133      }

134
135      wait.Set();
136    }

137  }
;
138
139  // 连接服务器
140  client.ConnectAsync(args);
141
142  // 等待处理结束
143  wait.WaitOne();
144}

145

如果不启动服务器策略文件服务,或者端口不是 943,你会在客户端获得一个 AccessDenied 错误。
当然,如果服务器监听端口不再允许范围(4502 - 4534)内,同样也会触发这样一个错误。


本文来自CSDN博客http://blog.csdn.net/zjfei/archive/2009/07/27/4384368.aspx

目录
相关文章
|
Web App开发 安全 .NET
一起谈.NET技术,保护您的 Silverlight 应用程序的安全
作为一名 Microsoft 服务顾问,我定期与客户和合作伙伴一起进行应用程序安全性讨论。 在本文中,我将介绍一些在这些讨论中提出的主题。 特别是,我将重点介绍编程人员在尝试保护 Silverlight 应用程序的安全时所面临的新挑战,而且我将考虑开发团队应该将其资源集中于哪些方面。
1239 0

热门文章

最新文章