创建Silverlight 5浏览器内受信应用

开发 后端
可以看到,在Silverlight 5中受信应用的权限几乎获得了与桌面应用相当的权限,在这里,我将为大家介绍如何创建浏览器内的受信应用。以下示例将通过Silverlight来监视本地的网络流量。

  在Silverlight 4中受信应用已经被支持,受信应用简单的说就是可以访问一些本地受限资源的Silverlight应用。在Silverlight 4中受信应用必须是OOB类型,即必须先安装在本地,同时受信应用能访问的资源也有限,例如只能访问我的文档、我的图片等位置的文件。而在Silverlight 5中受信应用的功能做了很大的改进和增强:

  受信应用可以运行于浏览器之内

  可以无限制的访问本地文件系统

  访问强安全性方法时,不会再引发MethodAccessException异常

  当运行于桌面模式时,可以创建多个窗口

  在Windows平台可以直接调用非托管函数

  可以看到,在Silverlight 5中受信应用的权限几乎获得了与桌面应用相当的权限,在这里,我将为大家介绍如何创建浏览器内的受信应用。以下示例将通过Silverlight来监视本地的网络流量。

  受信应用的创建与常规Silverlight应用没有差异,直接通过新建项目来创建:

  要使应用受信任,必须修改项目的属性,必须勾选“允许在浏览器外允许程序”,以及“在浏览器内运行时需要提升的权限”:

  单击浏览器外设置按钮,进入以下设置界面,勾选“在浏览器之外运行时需要提升的信任”,由于我们的应用只允许在浏览器内运行,所以可将“显示安装菜单”的复选框去掉。这里说明一下,由于受信应用在Silverlight之前版本是和浏览器外运行绑定的,所以这里我们可以看到,虽然现在不使用浏览器外运行方式,但也需要对OOB进行设置,以此来获取受信模式。

  实现功能。我们将调用非托管的Win32 API来实现本地网络流量的监视,在Silverlight 5中,调用本地非托管函数的方式与.NET下完全一致。具体请参照本文源码,代码片段:

  1. public static class WIN32API  
  2.     {  
  3.         [DllImport("kernel32.dll")]  
  4.         public static extern bool GetComputerName(StringBuilder computerName, out Int32 nameLength);  
  5.  
  6.         [DllImport("Iphlpapi.dll")]  
  7.         private static extern Int32 GetIfTable(Byte[] pIfTable, out long pdwSize, bool bOrder);  
  8.  
  9.         [DllImport("kernel32.dll")]  
  10.         private static extern  int MultiByteToWideChar(uint CodePage,Int32 dwFlags,byte[] lpMultiByteStr,Int32 cbMultiByte,byte[] lpWideCharStr, int cchWideChar);  
  11.  
  12.         public static MIB_IFTABLE GetIfTable()  
  13.         {  
  14.             MIB_IFTABLE table = new MIB_IFTABLE();  
  15.             long size = 0;  
  16.             GetIfTable(nullout size, false);  
  17.             if (size != 0)  
  18.             {  
  19.                 Byte[] data = new Byte[size];  
  20.                 long ret = GetIfTable(data, out size, false);  
  21.                 if (ret == 0)  
  22.                 {  
  23.                     MemoryStream ms = new MemoryStream(data);  
  24.                     ms.Position = 0;  
  25.                     BinaryReader br = new BinaryReader(ms, Encoding.Unicode);  
  26.  
  27.                     table.dwNumEntries = br.ReadInt32();  
  28.                     table.table = new MIB_IFROW[table.dwNumEntries];  
  29.                     for (int i = 0; i < table.dwNumEntries; i++)  
  30.                     {  
  31.                         table.table[i] = new MIB_IFROW();  
  32.                         MIB_IFROW curRow = table.table[i];  
  33.                         FieldInfo[] fis = typeof(MIB_IFROW).GetFields();  
  34.                         foreach (FieldInfo fi in fis)  
  35.                         {  
  36.                             if (!fi.IsStatic)  
  37.                             {  
  38.                                 MarshalAsAttribute[] attrs = fi.GetCustomAttributes(typeof(MarshalAsAttribute), trueas MarshalAsAttribute[];  
  39.                                 if (attrs != null && attrs.Length > 0 && attrs[0].SizeConst != 0)  
  40.                                 {  
  41.  
  42.                                     if (fi.FieldType == typeof(String))  
  43.                                     {  
  44.                                         Byte[] tmpChars = br.ReadBytes(attrs[0].SizeConst*2);  
  45.                                         fi.SetValue(curRow, Encoding.Unicode.GetString(tmpChars, 0, tmpChars.Length).TrimEnd('\0'));  
  46.                                     }  
  47.                                     else if (fi.FieldType == typeof(Byte[]))  
  48.                                     {  
  49.                                         fi.SetValue(curRow, br.ReadBytes(attrs[0].SizeConst));  
  50.                                     }  
  51.                                 }  
  52.                                 else 
  53.                                 {  
  54.                                     if (fi.FieldType == typeof(Int32))  
  55.                                     {  
  56.                                         Int32 tmpValue = br.ReadInt32();  
  57.                                         fi.SetValue(curRow, tmpValue);  
  58.                                     }  
  59.                                 }  
  60.  
  61.                             }  
  62.                         }  
  63.                     }  
  64.                 }  
  65.             }  
  66.  
  67.             return table;  
  68.         }  
  69.  
  70.         public static String AsciiToUTF8(Byte[] asciiBytes)  
  71.         {  
  72.             int mustBytes = MultiByteToWideChar(WIN32CONST.CP_ACP, WIN32CONST.MB_PRECOMPOSED, asciiBytes, -1, null, 0);  
  73.             if (mustBytes > 0)  
  74.             {  
  75.                 Byte[] tmpBytes = new Byte[mustBytes*2];  
  76.                 if (MultiByteToWideChar(WIN32CONST.CP_ACP, WIN32CONST.MB_PRECOMPOSED, asciiBytes, -1, tmpBytes, mustBytes) != 0)  
  77.                 {  
  78.                    return Encoding.Unicode.GetString(tmpBytes, 0, tmpBytes.Length);  
  79.                 }  
  80.             }  
  81.             return "";  
  82.         }  
  83.     } 


 

 

 

 

  1. 测试,当在本地测试时,即访问地址为localhost或127.0.0.1时,受信应用无需做任何设置即可运行,本示例运行结果如下:
    4
  2. 接下来我们将说明如何部署受信应用,首先,要使受信应用在远程客户机上被访问,必须对xap进行签名。
  3. 进入TrustedApp项目属性,转到签名页,勾选“为Xap文件签名”,这里我们将创建一个新的测试证书,以此进行演示,实际项目中可以向证书颁发机构申请信任证书,当然这是需要$的。单击创建新测试证书按钮,在弹出对话框中输入密码,这里设置为test,确定后,Visual Studio将创建一个证书文件,默认保存在项目根目录下。
    5
  4. 接下来单击“从存储区选择”按钮,在弹出窗口中选择刚才创建的证书
    6
  5. 在签名页面,单击“更多详细信息”按钮,将会显示证书的详细信息,选择详细信息标签,然后单击“复制到文件”按钮,进入证书导出向导:
    7 
  6. 进入以下页面后,选择不要导出私钥:
  7. 8 
  8. 此步骤导出的证书供客户端使用!
  9. 完成后重新生成解决方案
  10. 将受信应用部署到IIS,部署与传统ASP.NET应用一样,无需做其他设置。
  11. 以上基本完成了服务端的设置,接下来对于客户端需要做一些设置,才能在浏览器内运行受信应用
  12. 首先需要启用浏览器内受信应用权限,这可直接通过修改注册表来完成:
    注册表路径:HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight\
    值名称:AllowElevatedTrustAppsInBrowser
    值类型:DWORD
    可用值:不可在浏览器内运行受信应用,设置为0,如果启用设置为1
  13. 在客户端安装第9步骤导出的证书,在证书文件上单击右键,选择安装,进入证书安装向导,选择存储区时,将证书导入到“受信任的发布者”位置:
    9
  14. 重复第14步骤,选择存储区时,将证书导入到“受信任的根证书颁发机构”位置。
  15. 到此,我们即可在此客户端上运行受信应用了(注意下图中的地址已经是非本机地址):
    10
  16. 但是,必须注意此时的Silverlight是没办法自动更新的,也就是说服务端xap更新后,客户端重新访问时不会去自动下载xap,这显然不符合需求,那该怎么做呢?我们需要在每次生成xap的时候,自动对xap进行时间戳签名。
  17. 进入到TrustedApp项目属性,选择生成事件:
    11
    在后期生成事件命令行中输入以下命令,进行xap的时间戳签名:
    "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\signtool.exe" sign /v /f "$(ProjectDir)TrustedApp_1_TemporaryKey.pfx" /p test /t http://timestamp.comodoca.com/authenticode $(TargetName).xap
    前面为signtool的全路径,它通常位于所安装的Windows SDK目录下, /f 后面跟随证书的全路径,以上示例表示当前项目下的TrustedApp_1_TemporaryKey.pfx证书文件,/p 后面表示证书的密码,/t 后面跟随一个CA Authenticode Timestamping Service的URL地址,命令***部分为需要签名的xap文件。
    进行此步操作后,每次生成xap文件后,Visual Studio将自动调用次命令进行xap的时间戳签名。这样,客户端重新访问网页时,即可自动下载更新xap。

 

责任编辑:彭凡 来源: 博客园
相关推荐

2009-12-31 15:58:11

Silverlight

2009-03-26 15:35:22

detachedRIASilverligh

2011-09-29 14:16:13

通信展手机Html5

2009-02-19 09:42:01

SliverlightChrome微软

2012-05-17 09:45:30

2009-03-22 10:08:25

SilverLight浏览器

2009-12-30 18:07:54

Silverlight

2009-12-15 13:47:33

Silverlight

2012-04-25 14:06:45

HTML5

2012-05-28 13:09:12

HTML5

2021-06-02 06:14:50

Nyxt浏览器

2012-05-07 14:24:15

HTML 5Web App

2020-10-29 09:45:58

零日漏洞Chrome攻击

2013-11-13 10:05:15

移动浏览器HTML 5

2012-03-20 11:07:08

2009-08-20 09:18:27

Silverlight

2012-03-19 17:25:22

2012-03-20 11:31:58

移动浏览器

2012-03-20 11:41:18

海豚浏览器

2012-03-20 11:22:02

QQ手机浏览器
点赞
收藏

51CTO技术栈公众号