天天看点

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

    一般来说,Internet 应用程序应该被限制直接访问重要系统资源的能力,以防止恶意的破坏。默认设置下,HTML 和客户端脚本语言都不能够访问关键的系统资源。 因为 Windows Presentation Foundation(WPF) 浏览器宿主应用程序可以从浏览器启动,它们也应遵循一组相似的限制。为了实施这些限制,WPF 同时依赖代码访问安全性 (CAS:Code Access Security) 和 ClickOnce (请参阅 Windows Presentation Foundation Security Strategy - Platform Security)。 默认设置下,浏览器宿主应用程序总是请求 ”Internet 区域“ CAS 组的权限,而不管它们是从 Internet、 本地 Intranet 或本地计算机启动的。 以任何小于完整权限集的权限运行的应用程序都被称为运行在部分信任安全环境中的应用程序。

    WPF 提供了多种支持以确保尽可能多的功能能够安全的用于部分信任环境,并且与CAS一道为部分信任环境编程提供了额外的支持。

    本主题包含以下各节:

    • 部分信任环境下支持的WPF特性
    • 部分信任环境下的编程
    • 管理 权限
    • 相关的主题

部分信任环境下支持的WPF特性

    下表列出了可以在Internet 区域权限集的限制下安全使用的WPF高级特性。

表 1:在部分信任环境下可以安全使用的 WPF 功能

功能区域 功能
常规

浏览器窗口

源站点访问

IsolatedStorage(隔离存储:512KB 限制)

UIAutomation 提供程序

命令

输入法 (IME)

Tablet Stylus and Ink

使用鼠标捕获和移动事件的模拟拖 / 放

OpenFileDialog

XAML 反序列化 (通过 XamlReader.Load)

Web 集成

浏览器下载对话框

用户启动的顶级导航

mailto:links

统一资源标识符参数

HTTPWebRequest

内嵌于IFRAME的WPF 内容

承载相同站点的 HTML 页

Web Services(ASMX)

视觉效果

2D和3D

动画

媒体 (源站点和跨域)

图像 / 音频 / 视频

图像编码

阅读

FlowDocuments

XPS 文档

嵌入式及系统字体

CFF和TrueType 字体

编辑

拼写检查

RichTextBox

纯文本和Ink剪贴板支持

用户启动的粘贴

复制选定的内容

控件 常用控件

    此表粗略概括了 WPF 功能, 有关更多详细信息请参见SDK文档,其中描述了WPF中每项功能所需要的权限。在部分信任环境中,以下WPF功能有特殊的注意事项:

    • XAML (请参阅 XAML 概述).
    • 弹出窗口 (请参阅 System.Windows.Controls.Primitives.Popup).
    • 拖放 (请参阅 拖/放概述). 
    • 剪贴板 (请参阅 System.Windows.Clipboard).
    • 图像处理 (请参阅 System.Windows.Controls.Image).
    • 序列化 (请参阅 System.Windows.Markup.XamlReader.Load, System.Windows.Markup.XamlWriter.Save).
    • 打开文件对话框 (请参阅 Microsoft.Win32.OpenFileDialog).

    下表概括了在Internet 区域权限集限制内不能安全运行的 WPF 功能。

表 2:在部分信任环境中不安全的WPF 功能

功能区域 功能
常规

窗口 (应用程序定义的窗口和对话框)

SaveFileDialog

文件系统

注册表访问

拖/放

XAML 序列化 (通过 XamlWriter.Save)

UIAutomation 客户端

源窗口访问 (HwndHost)

完全语音支持

Windows Forms 互操作性

Web 集成

Web Services( Windows Communication Foundation)

脚本

文档对象模型(DOM)

视觉效果 位图效果
编辑

RTF 格式剪贴板

完全 XAML 支持

部分信任环境下的编程

    对于 XBAP 应用程序(WPF Browser Application),超出默认的 Internet 区域权限集的代码将被CAS检测    到,并且将引发安全异常导致应用程序终止。 在保护用户的同时,这种方式却并没有提供最佳的用户体验。

     一般而言,可能会超过所允许的权限的代码很可能是那些在独立的应用程序和浏览器宿主应用程序之间共享的代码。CAS 和 WPF 提供几种技术来处理这种情况。

使用CAS检测权限

    在某些情况下,库程序集中的共享代码可能同时用于独立的应用程序和 XBAP应用。 在这些情况下,代码可能执行需要比应用程序授予的权限集更多权限的功能。通过使用 Microsoft NET Framework  3.0的安全机制,应用程序可以检测它是否拥有特定的权限。特别的,它可以通过在所需的权限实例上调用 Demand 方法来测试它是否拥有特定的权限。在下面的示例代码中,将展示如何通过代码查询是否能将文件保存到本地磁盘:

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

public   class  SharedClass

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

... {

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

    ...

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

    public static void Save()

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        if( IsPermissionGranted(new FileIOPermission(FileIOPermissionAccess.Write, @"c: ewfile.txt") ) ) ...{

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            // Write to local disk

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            using (FileStream stream = File.Create(@"c: ewfile.txt"))

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            using (StreamWriter writer = new StreamWriter(stream))

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            ...{

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

                writer.WriteLine("I can write to local disk.");

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        else

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        ...{

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            MessageBox.Show("I can't write to local disk.");

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

    }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

     //  Detect whether or not this application has the requested permission

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

     bool  IsPermissionGranted(CodeAccessPermission requestedPermission)

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

     ... {

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        try

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        ...{

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            // Try and get this permission

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            requestedPermission.Demand();

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            return true;

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        catch

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅
WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        ...{

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

            return false;

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

        }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

    }

WPF部分信任安全部分信任环境下支持的WPF特性部分信任环境下的编程管理权限请参阅

}       

    如果应用程序没有所需的权限, Demand调用将引发安全异常。否则,权限将被授予。 IsPermissionGranted 方法 封装此行为并相应返回 true 或 false。

优雅的功能降级

    对于可以从不同的区域执行的代码,关注的是能够检测代码是否具有所需的权限。虽然检测区域是一种解决方法,但如果可能的话,最好能够为用户提供一种替代方法。 例如,完全信任的应用程序通常能让用户在任何想要的位置上创建文件,而部分信任的应用程序只能在独立存储区中创建文件。 如果创建文件的代码位于共享的程序集 (.dll)中,而该程序集被完全信任 (独立的应用程序) 和部分信任 (浏览器的宿主应用程序)所共享,并且这两种应用程序都希望用户能够创建文件,那么共享代码在适当的位置创建一个文件之前应该检测它是在部分信任环境中运行还是在完全信任环境中运行。以下的代码演示了这两种情况:

public   class  SharedClass

{

     public   static   void  Save()

    {

         if ( IsPermissionGranted( new  FileIOPermission(FileIOPermissionAccess.Write,  @" c: ewfile.txt " ) ) ) {

             //  Write to local disk

             using  (FileStream stream  =  File.Create( @" c: ewfile.txt " ))

             using  (StreamWriter writer  =   new  StreamWriter(stream))

            {

                writer.WriteLine( " I can write to local disk. " );

            }

        }

         else

        {

             //  Persist application-scope property to 

             //  isolated storage

            IsolatedStorageFile storage  =  

              IsolatedStorageFile.GetUserStoreForApplication();

             using  (IsolatedStorageFileStream stream  =  

               new  IsolatedStorageFileStream(

                 " newfile.txt " , FileMode.Create, storage))

             using  (StreamWriter writer  =   new  StreamWriter(stream))

            {

                writer.WriteLine(

                   " I can write to Isolated Storage " );

            }

        }

    }

     //  Detect whether or not this application has the requested permission

     bool  IsPermissionGranted(CodeAccessPermission requestedPermission)

    {

         try

        {

             //  Try and get this permission

            requestedPermission.Demand();

             return   true ;

        }

         catch

        {

             return   false ;

        }

    }

}

    在很多情况下,您应该能够找到一个部分信任环境下的替代方法。在一个受控环境中(例如Intranet),自定义的托管程序集可以安装到客户端的全局程序集缓存 (GAC)中。 这些共享库可以执行需要完全信任的代码,并且通过使用 AllowPartiallyTrustedCallersAttribute (请参阅 Windows Presentation Foundation Security 和  Windows Presentation Foundation Security Strategy - Platform Security 获得详细信息)让只允许部分信任的应用程序所引用。

浏览器主机检测

     当您需要在每权限基础上进行检查时,使用 CAS 来检查权限是一种合适的技术。 然而,这种技术依赖于将捕获异常作为正常处理流程的一部分,通常并不推荐这么做,并且可能会有性能方面的问题。如果您的 XAML 浏览器应用程序 (XBAP) 只运行在 Internet 区域沙箱中,那么您可以使用 System.Windows.Interop.BrowserInteropHelper.IsBrowserHosted ,对于 XAML 浏览器应用程序 (XBAPs)它返回true。以下是代码示例:

namespace  SharedPages

{

     using  System;

     using  System.Windows;

     using  System.Windows.Interop;

     using  System.Windows.Navigation;

     public   class  TaskLauncher : PageFunction < TaskContext >

    {

        TaskData taskData  =   new  TaskData();

         protected   override   void  Start()

        {

             //  Retain instance (and state) in navigation history until task is complete

             this .KeepAlive  =   true ;

             this .WindowTitle  =   " Task Launcher " ;

             //  Is this assembly running in a browser-hosted application (XBAP)?

             if  (BrowserInteropHelper.IsBrowserHosted)

            {

                 //  If so, use browser-style UI

                UseTaskPageUI();

            }

             else

            {

                 //  If not, use window-style UI

                UseTaskDialogBoxUI();

            }

        }

         #region  Task Page UI

         void  UseTaskPageUI()

        {

             //  Launch the task

            TaskPage taskPage  =   new  TaskPage( this .taskData);

            taskPage.Return  +=   new  ReturnEventHandler < TaskResult > (taskPage_Return);

             this .NavigationService.Navigate(taskPage);

        }

         void  taskPage_Return( object  sender, ReturnEventArgs < TaskResult >  e)

        {

             //  Task was completed (finished or canceled), return TaskResult and TaskData

            OnReturn( new  ReturnEventArgs < TaskContext > ( new  TaskContext(e.Result,  this .taskData)));

        }

         #endregion

         #region  Task Dialog Box UI

         void  UseTaskDialogBoxUI()

        {

             //  Create and show dialog box

            TaskDialog taskDialog  =   new  TaskDialog( this .taskData);

            taskDialog.Owner  =  Application.Current.MainWindow;

             bool  dialogResult  =  ( bool )taskDialog.ShowDialog();

            TaskResult taskResult  =  (dialogResult  ==   true   ?  TaskResult.Finished : TaskResult.Canceled);

             //  Return results

            OnReturn( new  ReturnEventArgs < TaskContext > ( new  TaskContext(taskResult,  this .taskData)));

        }

         #endregion

    }

}

注意:
IsBrowserHosted 只判断应用程序是否在浏览器中运行,而不管应用程序是以哪一组权限在运行。

管理权限

    默认情况下,XBAP应用程序运行于部分信任环境 (默认的 Internet 区域权限集)。 但是根据应用程序的要求,它可以更改权限集而不再使用默认值。 例如,如果一个 XBAP是从本地Intranet启动的,那么它就可以充分利用增加的权限集下, 如下表3所示。

表 3: LocalIntranet 和 Internet 权限

权限 属性 LocalIntranet Internet
DNS 访问 DNS 服务器
环境变量 读取
文件对话框 打开
文件对话框 不受限制
独立存储 由用户的程序集隔离
独立存储 未知的隔离
独立存储 无限制的用户配额
媒体 安全的音频、 视频和图像
打印 默认打印
打印 安全打印
反射 发出(Emit)
安全 托管代码执行
安全 断言授予的权限
用户界面 不受限制
用户界面 安全的顶级窗口
用户界面 拥有剪贴板
Web 浏览器 到 HTML的安全框架导航

        如果您要增加权限,您可以使用下列工具之一:

    • Manifest Generation and Editing Tool (Mage.exe)
    • Manifest Generation and Editing Tool, Graphical Client (MageUI.exe)
    • Visual Studio ClickOnce Deployment and Security.

    如果您的 XBAP 需要完全信任,可以使用相同的工具来增加所请求的权限,尽管一个 XBAP应用程序只有被安装到本地计算机并且从本地计算机上启动时才能得到完全信任。这这意味着你失去了在将XBAP发布到 Web 服务器时所获得的自动更新支持。

请参阅

Windows Presentation Foundation Security

Windows Presentation Foundation Security Strategy - Platform Security

Windows Presentation Foundation Security Strategy - Security Engineering