WPF部分信任安全

翻译 2007年09月15日 13:34:00

    一般来说,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特性

    下表列出了可以在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功能有特殊的注意事项:


    下表概括了在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 方法来测试它是否拥有特定的权限。在下面的示例代码中,将展示如何通过代码查询是否能将文件保存到本地磁盘:

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
        
{
            MessageBox.Show(
"I can't write to local disk.");
        }

    }

    
    
// 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;
        }

    }

}
      
    如果应用程序没有所需的权限, 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的安全框架导航

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


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

请参阅


相关文章推荐

深入浅出学WPF窗口- [WPF学习总结]

深入浅出是个好词,侯大侠的《深入浅出MFC》,最近还在看一本也是以深入浅出为标题的书籍。觉得深入去了解程序实现背后的原理才是真正的透彻掌握一门知识,最近虽然在学习WPF,但感觉没有什么实质性的学习成果...

WPF与JS 函数、回调函数调用

WPF代码 namespace WPFJsTest { /// /// Page1.xaml 的交互逻辑 /// public partial class Pag...

WPF学习笔记 - .Net Framework的分离存储技术

写入: protected override void OnClosed(EventArgs e) {     base.OnClosed(e);     IsolatedStorageFil...

web安全认证机制知多少

如今web服务随处可见,成千上万的web程序被部署到公网上供用户访问,有些系统只针对指定用户开放,属于安全级别较高的web应用,他们需要有一种认证机制以保护系统资源的安全,本文将探讨五种常用的认证机制...

WCF:在 WCF Web 服务和 SharePoint 2010 安全令牌服务之间建立信任关系(第 3 部分,共 4 部分)

目录简介创建自签名证书将证书绑定到 HTTPS导出自签名证书在 Web 服务和 SharePoint Foundation 2010 之间建立信任关系确定 SharePoint 安全令牌服务证书的指纹...

WPF发布程序后未授予信任的解决办法

WPF发布程序后未授予信任的解决办法 基于浏览器的WPF应用程序由于需要比较高的操作权限,所以在项目的安全性属性中选择了“这是完全可信的应用程序”选项。可是,在发布部署后,在其他电脑上打开xbap文...
  • zztfj
  • zztfj
  • 2013年08月07日 17:47
  • 4259
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WPF部分信任安全
举报原因:
原因补充:

(最多只允许输入30个字)